54 Commits
Author SHA1 Message Date
Alvaro Fuentes 1bc016fa0f [FIX] core: remove SQL constraints upon ir.model.constraint removal
Otherwise we leave the constraints in the table. Common source of
upgrade issues.

closes odoo/odoo#163623

X-original-commit: 847a24e6f7f57c755cf6f42597b1ac75908f2c83
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2024-04-29 08:07:30 +00:00
Alvaro Fuentes b278241a71 [FIX] base: ensure existing ir.model.constraint xmlids are loaded
When we load a module and the SQL constraints exist both in the table
and in `ir_model_constraint` we need to ensure the xmlid is loaded.
Otherwise the record in `ir_model_constraint` is removed.

Since 4c9968397b we skip returning
existing non-updated constraint records in `_reflect_constraint`. This
leads to them being removed by the ORM. At the end of the load the ORM
sees the record in `ir_model_data` but not in the xmlid pool, thus it
removes it.

closes odoo/odoo#162105

X-original-commit: b5670c7f0d35d13affee2ae93158556346b7dd23
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
2024-04-16 17:38:14 +00:00
Alvaro FuentesandChristophe Simonis c18b9f44be [IMP] *: optimize multi-company rule
When we use the `|` (or) version of this rule the ORM generates two
sub-queries when checking the company. This causes sub-optimal and in
some cases really bad planning for the queries and thus PG takes hours
to complete them.

Example (formatted):
```sql
    SELECT "mrp_routing_workcenter".id
      FROM "mrp_routing_workcenter"
 LEFT JOIN "mrp_bom" AS "mrp_routing_workcenter__bom_id"
        ON "mrp_routing_workcenter"."bom_id" = "mrp_routing_workcenter__bom_id"."id"
     WHERE "mrp_routing_workcenter"."workcenter_id" in (1)
       AND (  ("mrp_routing_workcenter"."bom_id" in (
                    SELECT "mrp_bom".id
                      FROM "mrp_bom"
                     WHERE ("mrp_bom"."company_id" in (1))
                   )
              )
           OR ("mrp_routing_workcenter"."bom_id" in (
                    SELECT "mrp_bom".id
                      FROM "mrp_bom"
                     WHERE "mrp_bom"."company_id" IS NULL
                   )
              )
           )
  ORDER BY "mrp_routing_workcenter__bom_id"."sequence",
           "mrp_routing_workcenter__bom_id"."id",
           "mrp_routing_workcenter"."sequence",
           "mrp_routing_workcenter"."id"
```

If we use the single term version the generated query has only one
sub-query:
```sql
    SELECT "mrp_routing_workcenter".id
      FROM "mrp_routing_workcenter"
 LEFT JOIN "mrp_bom" AS "mrp_routing_workcenter__bom_id"
        ON "mrp_routing_workcenter"."bom_id" = "mrp_routing_workcenter__bom_id"."id"
     WHERE "mrp_routing_workcenter"."workcenter_id" in (1)
       AND (  ("mrp_routing_workcenter"."bom_id" in (
                    SELECT "mrp_bom".id
                      FROM "mrp_bom"
                     WHERE (("mrp_bom"."company_id" in (1))
                        OR  ("mrp_bom"."company_id" IS NULL))
                   )
              )
           )
  ORDER BY "mrp_routing_workcenter__bom_id"."sequence",
           "mrp_routing_workcenter__bom_id"."id",
           "mrp_routing_workcenter"."sequence",
           "mrp_routing_workcenter"."id"
```
In this version PG is able to produce a better query plan resulting in
better execution times.

Also, the `company_id` field is required on some models, so the "= False" comparison is useless.

closes odoo/odoo#159123

X-original-commit: 1b5c41f36801fb886ec591f29dba42787d698526
Related: odoo/enterprise#59378
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
Co-authored-by: Christophe Simonis <chs@odoo.com>
2024-03-25 17:50:06 +00:00
Alvaro Fuentes 084d2bcd46 [FIX] mail: correctly compute groups on trackings, depending on model
Side effect due to a combination of odoo/odoo#124182 making field_id not
required to keep trackings when removing fields, and odoo/odoo@9c9552fd20
where field is used to find model when computing groups instead of message
in case the tracking is logged on a model different from the field model
e.g. accounting.

Steps to reproduce:
1. Install project_enterprise in saas-16.4
2. Create a task and update some values for Date deadline
3. Upgrade to 17.0
4. Try to open the task in the upgraded DB.

We get an error:
```
ValueError('All tracking value should belong to the same model.')
```

The reason is that `date_deadline` field is removed during the upgrade
and thus `fields_models` is empty in
https://github.com/odoo/odoo/blob/0649134444fa6b26de1c8c25d7c4a3f70c6d64e0/addons/mail/models/mail_tracking_value.py#L120-L121

closes odoo/odoo#156571

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2024-03-05 19:21:39 +00:00
Alvaro Fuentes 0db60bf1c2 [FIX] mail: fix tracking formatting when having several models
In odoo/odoo@9c9552fd20 a support of tracking value belonging to another model
than the message has been added. In such cases the formatting method written
at odoo/odoo#124182 fails as it expects a single model for all tracking values
it receives. When field is removed 'model' is False, and we fallback on
mail_message model.

Part-of: odoo/odoo#156571
2024-03-05 19:21:39 +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
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
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
Alvaro Fuentes 04266116f2 [FIX] hr: fix error on avatar computation in multi-comp
The user associated to an employee doesn't need to be in the same
company of the employee. When this happens, we could get a multi company
issue when trying to _only_ display the employee form.

One way this issue is triggered is when the partner of the associated
user is marked as partner_share=True. We may get an access error due to
the rule `base.res_partner_rule`.

Steps to reproduce:
1. Install HR module
2. Create an extra company with a user (U) on it. Ensure the partner of
   U is also set as belonging to this second company.
3. Create an employee in the first company with associated user U.
4. Archive U (this makes the partner of U get partner_share=True)
5. Try to access the employee form from the first company.

We get an error:
```
Due to security restrictions, you are not allowed to access 'User' (res.users) records.

Records: U (id=11, company=COMP2)
User: Mitchell Admin (id=2)

This restriction is due to the following rules:
- user rule

Note: this might be a multi-company issue.

Contact your administrator to request access if necessary.

Implicitly accessed through 'User' (res.users).
```

Since we allow hr.employee records to keep the associated archived user,
to avoid this issue (potentially triggered differently) we opt to
compute the avatar placeholder as sudo.

The issue has been observed in multiple upgrade requests.

closes odoo/odoo#149171

X-original-commit: 5136e86b4d47fae1a70cba0809906cfc625fd1de
Signed-off-by: Sofie Gvaladze (sgv) <sgv@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2024-01-12 11:18:04 +00:00
Alvaro Fuentes 4b096631ad [FIX] core: include inactive companies in _check_company
`res.users.company_ids` returns only active companies, while
`res.users.company_id` may be inactive. This leads to a situation where
`self.env.company` is inactive but still associated to `self.env.user`.

Since in multiple cases the default value for relational fields pointing
to `res.users` is `self.env.user`, we may get an error in this check:
`self.env.company` is not in `self.env.user.company_ids`.

See https://github.com/odoo/odoo/blob/5506ca7/odoo/addons/base/models/res_users.py#L281-L282

closes odoo/odoo#147127

Signed-off-by: Raphael Collet <rco@odoo.com>
2024-01-08 20:38:03 +00:00
Alvaro Fuentes 74c291ef5f [FIX] hr_work_entry_holidays: fix dates computaiton in write
We need to filter out records without `request_date_from` and
`request_date_to` to avoid the error:
```
  File "/tmp/tmpiaelju95/odoo/17.0/addons/hr_work_entry_holidays/models/hr_leave.py", line 180, in write
    stop = datetime.combine(max(stop_dates) + relativedelta(days=1), time.max)
TypeError: '>' not supported between instances of 'datetime.date' and 'bool'
```

Issue observed in test upgrades of `l10n_hk_hr_payroll`

closes odoo/odoo#140286

Signed-off-by: Sofie Gvaladze (sgv) <sgv@odoo.com>
2023-11-02 15:10:58 +00:00
Alvaro Fuentes f7cd412725 [FIX] core: fix remove constraints at uninstall
This patch aims to fix multiple issues with the removal of table
constraints at module uninstall.

1. We cannot remove `ir.model.constraint` records before calling
   `_module_data_uninstall` on them. Otherwise we either won't find them
   when performing the search
   `self.env['ir.model.constraint'].search([('module', 'in',
   modules.ids)]` or, if we somehow keep the ids and use `browse`
   instead, would get an error because `_module_data_uninstall` tries to
   access field values of records already removed. Note, although not an
   issue, the removal is redundant for non FK constraints since
   `_model_data_uninstall` already unlinks the record.
2. When a constraint has a name longer than 63 characters (Postgres
   default) we would fail the check for the existence of the constraint
   since the names are truncated.
3. When checking for the presence of a constraint we assumed its type
   would be `u` in `pg_constraint` because for us that means non FK
   (i.e. not `f` type). That's incorrect since there are many more
   types. Here we propose to handle `c,u,x` types.

For bullet 2 we use `tools.make_identifier` that hashes the name and
ensures it fits in the 63 chars limit.

Revert "[IMP] models: warn if constraint key len exceed 63"

The check from commit 823d9e10dc is no
longer needed since the name is ensured to fit length limit.

[IMP] code: improve uninstall tests

Perform extra checks for removal of SQL constraints. Note the test is
commented out in `__init__.py`. It can be uncommented locally for
testing. It's kept commented out to avoid random errors in runbot.

closes odoo/odoo#129084

X-original-commit: af288b7178c25261329dd85a2e64b9dd635cd9e1
Signed-off-by: Raphael Collet <rco@odoo.com>
2023-08-16 16:04:47 +02:00
Alvaro Fuentes bade33c935 [FIX] account: fix CoA translations load
This patch solves two issues when loading translations from CSV files.
1. If there is a CoA from a custom module that is not available the load
   fails.
2. If there is an uninstalled CoA in use some of its fields may be
   missing thus loading values from CSV files may fail.

Both issues were observed during upgrades.

closes odoo/odoo#129068

X-original-commit: f2b2260683a284801aa0aa55850cfecb4a0ff0e4
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2023-07-20 10:07:14 +02:00
Alvaro Fuentes e50f762aa9 [FIX] point_of_sale: fix memory error
When there are too many (millions) of POS order lines associated to
opened POS sessions we get too many taxes, most are duplicated. This
causes a MemorryError.

Example queries from a real DB:
```
> select count(distinct r.account_tax_id) from pos_order_line l join pos_order o on o.id = l.order_id join pos_session s on s.id = o.session_id join account_tax_pos_order_line_rel r on r.pos_order_
 line_id = l.id where s.state != 'closed'
+-------+
| count |
|-------|
| 24    |
+-------+
> select count(r.account_tax_id) from pos_order_line l join pos_order o on o.id = l.order_id join pos_session s on s.id = o.session_id join account_tax_pos_order_line_rel r on r.pos_order_line_id =
  l.id where s.state != 'closed'
+---------+
| count   |
|---------|
| 2504539 |
+---------+
```

opw-3295467

closes odoo/odoo#124990

X-original-commit: b5870af0fd74118d96cbd130f3b319e2319d82f8
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
2023-06-15 01:20:15 +02:00
Alvaro Fuentes 30fd0071a2 [FIX] account: use more efficient method
Check accounting entries in a more effective way.

closes odoo/odoo#124755

X-original-commit: 316c1d9745af33d85bd94747b3d913d9c9db2342
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2023-06-13 10:13:58 +02:00
Alvaro Fuentes 8bcca1a267 [FIX] account: do not change company's currency on CoA load
If the company already has some accounting entries we shouldn't override
its currency. This is useful to avoids errors related to existing
journal items for the current company's currency.

Issue observed during upgrades for MX localization.

X-original-commit: 752a20596cf132d1641abed7eacb5d53a695869a
Part-of: odoo/odoo#124755
2023-06-13 10:13:57 +02:00
Alvaro FuentesandChong Wang f7fca3faf9 [FIX] core: do not udpate translation terms from text to xml
Steps to reproduce the issue:
* In a clean v16 db install base_setup
* Log in into DB, switch language to French (install and activate it)
* Upgrade to saas-16.1

Issue: The main settings page under Companies settings (Sociétés in Frech) shows
```
<span class="o_form_label">Mise en page du document</span> <span class="fa fa-lg fa-building-o" title="Les valeurs définies ici sont spécifiques à l'entreprise." aria-label="Values set here are company-specific." groups="base.group_multi_company" role="img"/>
```
instead of just
```
Mise en page du document
```

The issue comes from this difference, 16.0:
https://github.com/odoo/odoo/blob/fb02720aed0b0be00df8f5d0e1932b948c300b92/addons/base_setup/views/res_config_settings_views.xml#L78-L79
vs saas-16.1:
https://github.com/odoo/odoo/blob/80bc702ecfe6f704af05f9830d272b162018f2ad/addons/base_setup/views/res_config_settings_views.xml#L79

Note that `Document Layout` is used in two different contexts. In 16.0
it comes within an xml/html block containing a `<span>` tag, and more
importantly it is the **text** part of the xml tag. In saas-16.1 the
same `Document Layout` is used as an **attribute** of the `setting` tag.
Thus we cannot blindly assign the whole term (block with tags) to the
attribute when upgrading to saas-16.1, it is only safe to update the
translation from xml to text. Updating a text entry with something that
seems to have other xml elements is unsafe and can lead to the issue
showcased here.

For more context, at the time of updating the terms here is the
situation:
* `closest_matches` is `['Document Layout']`
* `closest_term` is `Document Layout`
* `old_term` is
  ```
  <span class="o_form_label">Document Layout</span>
                                        <span class="fa fa-lg fa-building-o" title="Values set here are company-specific." aria-label="Values set here are company-specific." groups="base.group_multi_company" role="img"/>
  ```

closes odoo/odoo#123540

X-original-commit: 6cd49293fe4d0d86fbbfa2476e113deadeba7348
Signed-off-by: Wang Chong (cwg) <cwg@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
Co-authored-by: Chong Wang(cwg) <cwg@odoo.com>
2023-06-02 23:38:58 +02:00
Alvaro Fuentes 854211cee7 [FIX] mrp: fix qty_available for kit with sub-kits
On this situation:
* P1 consumable product, kit, with components P2 and P3 in its BoM using
  1 of each
* P2 comsumable product, kit, with component P3 using 1 in the BoM
* P3 storable product, 10 units in stock

Before:
The qyt_available for P1 is 10. That's incorrect: to assemble one P1 we
need precisely two of P3s, one for P2 BoM then an extra for P1 BoM.

After:
The qyt_available for P1 is 5.

closes odoo/odoo#122939

X-original-commit: b32554322d4c26665bdcb29fd58bb95f12faa20e
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2023-05-31 09:23:13 +02:00
Alvaro Fuentes 6f6fb10511 [FIX] mail: allow to create a manual blacklist model
Issue 1: before this patch it was impossible to create a manual model
marked as "Is blacklist". The reason is that a blacklist model
implicitly need an `email` field, but such field is impossible to add in
a manual model: the field must start with `x_`.

Solution: append `x_` to the implicit email field. Note, in principle
the user gets an error if `x_email` is not present. Solved by adding the
field when creating the custom model. Ideally we should show some hint
in the interface to make it more user friendly. That is out of the scope
of this patch.

Issue 2: when we have a manual model that is mail blacklist it's
impossible to create its model class. We get an error because the MRO is
not correct. The reason is that we are adding `mail.thread.blacklist`
_after_ `mail.thread` in the `_inherit` list. That list is used to
generated the `__bases__` of the model class[1]. According to Python's
MRO rules[2], since `mail.thread.blacklist` appears after `mail.thread`
as parents of the custom model class this order _must_ be respected. But
`mail.thread` must appear _before_ `mail.thread.blacklist` because the
latter inherits from the former. This is a contradiction and the MRO
algorithm cannot succeed. To put it in a simple example:
```py
class A: pass
class B(A): pass
 # This fails:
 # class C(A, B): pass
 # The right order is:
class C(B, A): pass
 # Equivalent to:
class D(B): pass
 # C and D have the same MRO linearization excluding themselves
assert D.mro()[1:] == C.mro()[1:]
```
Example traceback:
```
Traceback (most recent call last):
  File "/home/odoo/src/odoo/14.0/odoo/service/server.py", line 1201, in preload_registries
    registry = Registry.new(dbname, update_module=update_module)
  File "/home/odoo/src/odoo/14.0/odoo/modules/registry.py", line 89, in new
    odoo.modules.load_modules(registry._db, force_demo, status, update_module)
  File "/home/odoo/src/odoo/14.0/odoo/modules/loading.py", line 464, in load_modules
    registry.setup_models(cr)
  File "/home/odoo/src/odoo/14.0/odoo/modules/registry.py", line 263, in setup_models
    env['ir.model']._add_manual_models()
  File "/home/odoo/src/odoo/14.0/odoo/addons/base/models/ir_model.py", line 430, in _add_manual_models
    Model = model_class._build_model(self.pool, cr)
  File "/home/odoo/src/odoo/14.0/odoo/models.py", line 585, in _build_model
    ModelClass.__bases__ = tuple(bases)
TypeError: Cannot create a consistent method resolution
order (MRO) for bases BaseModel, mail.thread, mail.thread.blacklist, base
```

Solution: check if a model inherits from `mail.thread.blacklist` first.
There is no need to add `mail.thread` if inheriting
`mail.thread.blacklist` because the inheritance is already implicit.

This issue was observed during upgrades. We convert custom models and
fields into manual to allow upgrading without custom code. This causes
issues because the MRO error appears when a custom model inherits mail
blacklist.

[1]: https://github.com/odoo/odoo/blob/02f820fb0eaddbb3a4269a0967184c8aaf52c363/odoo/models.py#L585
[2]: https://www.python.org/download/releases/2.3/mro/

closes odoo/odoo#120977

X-original-commit: 8848bb57ff7f086d801178c582d7f6371eeb8479
Signed-off-by: Christophe Simonis <chs@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2023-05-10 21:18:03 +02:00
Alvaro Fuentes 2f3e8ef154 [FIX] core: fix majorless upgrade
When we compare majorless scripts we must ignore the Odoo version.
Otherwise a module upgrade without major Odoo upgrade would fail to run
local scripts majorless scripts. That's what happens for example when
users click the upgrade button of a module.

Example: upgrade from `11.0.1.0` to `11.0.2.0`, with a local `2.0` folder
for upgrades.
```
11.0.1.0 < 11.0.2.0 < 11.0.2.0 -> False (check before this patch)
     1.0 <      2.0 <=     2.0 -> True  (check with this patch)
```
While still: upgrade from `11.0.2.0` to `12.0.2.0`
```
11.0.2.0 < 12.0.2.0 < 12.0.2.0 -> False (before this patch)
     2.0 <      2.0 <=     2.0 -> False (with this patch)
```

closes odoo/odoo#119203

X-original-commit: 84ab74c62a19d08de8b6c7c4e3f3300d7e79bcf9
Signed-off-by: Christophe Simonis <chs@odoo.com>
2023-04-20 15:22:04 +02:00
Alvaro Fuentes 549b3a0d0a [FIX] sale_timesheet: allow install of demo data
The product `sale_timesheet.product_service_deliver_milestones` uses
`milestones` service_type but this is not available always.

Steps to reproduce issue:
1. Install sale_praject (with demo) in a clean DB
2. Unmark "Use milestones" in settings
3. Set invoice policy at delivery in settings
4. Try to install sale_timesheet
Demo data fails to install due to attempt to use milestores as service
type.
```
  File "/home/odoo/src/odoo/16.0/odoo/fields.py", line 2720, in convert_to_cache
    raise ValueError("Wrong value for %s: %r" % (self, value))
```

This issue blocks many upgrades.

closes odoo/odoo#116697

X-original-commit: 8ae7bf6c9a3af45353e5ef43d8b72f95c6731e5f
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
2023-03-27 18:12:42 +02:00
Alvaro Fuentes cec6e163c1 [FIX] base: don't fail on empty groups attribute
In 15.0 this was supported. It may be also handy when editing views to
momentarily set the groups to `""`.

Steps to reproduce:
1. Install Odoo 15 locally
2. Edit or create a view with `groups=""` for some component
3. Upgrade to 16.
It fails.

Empty groups was allowed in 15.0 we want to ensure this is not broken
unintentionally anymore, such a new test was added.

Muted logged to hide the warning (also present in 15.0):
```
2023-02-08 11:09:18,697 506777 WARNING test_16_gr odoo.addons.base.models.ir_ui_view: The group '' defined in view does not exist!
View error context:
{'file': None,
 'line': 3,
 'name': 'foo',
 'view': ir.ui.view(242,),
 'view.model': 'res.partner',
 'view.parent': ir.ui.view(),
 'xmlid': ''}
 ```

closes odoo/odoo#112246

X-original-commit: 4379dce95edcc34a8e97e73a3bdaa2e20fdc79a8
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2023-02-09 10:49:06 +01:00
Alvaro Fuentes f385cd62de [FIX] hr_recruitment: set view priority
The view `hr_job_search_view` needs an xpath anchor set on the view
`view_job_filter_recruitment`. Since both views have default priority
the order they are applied depends on their ID. In a normal install
process the views are created in the right order, but there are cases
where the IDs are not on the right order.

Steps to reproduce:
1. Install hr_recruitment in 15.0
2. Remove the view pointed by view_job_filter_recruitment
3. Update to 16.0

We get an error:
```
ValueError: Element '<xpath expr="//filter[@name=&#39;my_favorite_jobs&#39;]">' cannot be located in parent view
```

closes odoo/odoo#111140

X-original-commit: 1e77fabfa087fbeedab974645646bc1761c07468
Signed-off-by: Christophe Simonis <chs@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2023-01-26 19:56:10 +01:00
Alvaro Fuentes b21ecab391 [FIX] mrp: avoid MemoryError in _get_orderpoint_products
`super()._get_orderpoint_products()` returns more than 1 million
products. Applying _bom_find to all of them is too much.
https://github.com/odoo/odoo/blob/55e327705deed2aa31c1fc9eca49a8a66135c020/addons/stock/models/stock_orderpoint.py#L567-L568

Issue observer on menu Inventory > Operations > Replenishment during
upgrades to 16.0

closes odoo/odoo#109311

X-original-commit: 263cb8eafb3ac0db5cb950e66dba3c924e52f187
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2023-01-09 10:11:27 +01:00
Alvaro Fuentes e382b70c69 [FIX] stock: avoid MemError on _get_orderpoint_action
When we have too many products from orderpoints we cannot compute the
forecasts for all at once. Otherwise we may get a MemoryError. Here we
iterate by chunks.

This error was observed on upg-417045, where there were 381927 prodcuts.

closes odoo/odoo#106196

X-original-commit: feea4e5f147b3b26cbc032daaf0ceabbe3417912
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2022-11-22 11:29:06 +01:00
Alvaro Fuentes 70c41dafd4 [FIX] mrp: improve perf of _skip_bom_line
The main motivation for this change is to improve performance of BoM
`explode`, which heavily rely on checking the lines to skip. `explode`
is also called from product `compute_quantities_dict` which is called
multiple times during upgrades. With this fix we improved the running
time of an upgrade _test_ from 3h:30m to 2h:55m which gives a 16%
performance improvement.

The goal of `_skip_bom_line` is to check that for each attribute present
on the line, at least one value associated to that attribute must be in
the attribute values of the product(*). If none is found then we
consider that we can skip the line.

The previous implementation was inefficient. It grouped all values by
attribute, then checked one by one if at least one value is on the
product. In case one attribute does not have any value on the product it
skipped the line.

The implementation we propose here is to take the intersection of the
product and line values, then check that their attributes are the same.
The later can be done with a simple length check. In case they are
different the line must be skipped. Note that this works because only
one value is possible per attribute in a product.

Both implementations are equivalent. The second is more efficient
because does not branch and relies on (record)set operations.

For example, let's consider a product with two attribute values
`a` and `b`, and a line with multiple values `a`,`y` for
attribute 1, and `z` for attribute 2.
```
Product                      Line
+---+                      +-----+
| a | <- same attribute -> | a,y |
+---+                      +-----+
| b | <- same attribute -> |  z  |
+---+                      + ----+
```
This line must be skipped. The reason is that the value `b` is not
among the list `[z]` of values for attribute 2 on the line. The new
implementation would get the intersection of attribute values as `[a]`
from there the comparison of the attributes will fail because `[a]` has
only one attribute while the line has two.

Let's consider a second case, where there is no value on the line for
attribute 2.
```
Product                      Line
+---+                      +-----+
| a | <- same attribute -> | a,y |
+---+                      +-----+
| b | <- same attribute -> |     |
+---+                      + ----+
```
This line is not skipped because there is no value for attribute 2 on
the line. Therefore the condition(*) per attribute is not violated for
this product. The new implementation gets `[a]` as intersection of values,
but now the attributes coincide: they are both attribute 1 for the
intersection and the line.

Finally,
```
Product                      Line
+---+                      +-----+
| a | <- same attribute -> | a,y |
+---+                      +-----+
|   | <- same attribute -> | z,w |
+---+                      + ----+
```
This line is skipped because none of `[z,w]` are in the product. The new
implementation would get again `[a]` as intersection which does not
match the attributes on the line.

closes odoo/odoo#105019

X-original-commit: 47f4c3cc72ecb612ef4edd8c603e27b698187d8a
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
2022-11-04 16:59:42 +01:00
Alvaro Fuentes adf534f2bf [FIX] payment: compute related_partner_ids with sudo
`related_partner_ids` is used in the form view of account.payment
https://github.com/odoo/odoo/blob/43fccd7aaa83117c95babc52d60dd1c26b28335a/addons/payment/views/account_payment_views.xml#L14
It is only needed for electronic payments to display the payment token
ids (as part of its domain)
https://github.com/odoo/odoo/blob/45f5167b956521f0a183ff1b1cc75fa1b273866c/addons/payment/models/account_payment.py#L13-L21
and for draft payments only.
https://github.com/odoo/odoo/blob/43fccd7aaa83117c95babc52d60dd1c26b28335a/addons/payment/views/account_payment_views.xml#L16

Before this change the form view will fail when partner_id has a company
that is not in the context. This is not incorrect, but it is unexpected
as `related_partner_ids` is not needed to just show the form view. A way
to reproduce the issue is to confirm a payment, then change the partner
company to a company not accessible for current user.

This causes issues during migrations: the form view for the failing
payments is displayed just fine for versions <=13.0

closes odoo/odoo#98623

X-original-commit: a126f007573a41d22108d9d7887f92b6926ef3ec
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2022-08-22 22:56:27 +02:00
Alvaro Fuentes 45c3121ce7 [FIX] stock: fix KeyError for archived warehouses
The below line raises a KeyError when `warehouse` refers to an archived
warehouse.
https://github.com/odoo/odoo/blob/01cc43b0578ecc9d1fed37a12b2468ffc9d4aedd/addons/stock/models/stock_orderpoint.py#L396

The reason is that the SQL view created on
https://github.com/odoo/odoo/blob/01cc43b0578ecc9d1fed37a12b2468ffc9d4aedd/addons/stock/report/report_stock_quantity.py#L28-L37
doesn't take into account whether the warehouses are archived or not.

The solution proposed here is to fetch all warehouses to ensure the
lookup doesn't fail. Alternatively the view could be updated but that
will be a bigger change.

This issue was detected during the upgrade 226754

closes odoo/odoo#97259

X-original-commit: aaa7fb8f2de6d2a0310215f694c5b1cd5d813ebe
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2022-08-01 20:41:11 +02:00
Alvaro Fuentes 27854c787a [IMP] test_base: test add/remove implied groups
Given a recordset R of (at least two) groups, and a group A.
We want to ensure that:
* `R._apply_group(A)` adds A to the list of implied groups of _all_
  groups in R.
* `R._remove_group(A)` removes A from the list of implied groups of
  _all_ groups in R

This is especially problematic for config settings of the form
```
class MyConfig(models.TransientModel):
    _inherit = 'res.config.settings'
    group_imply_A = fields.Boolean('x',implied_group='A',group='B1,B2')
```
since activating the implication via `group_imply_A=True` currently
fails in case only one of B1,B2 already implies A.

opw-2832741

closes odoo/odoo#96928

X-original-commit: 81dc64740ba46355462ed2169e57fc0ce694ccdb
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2022-07-28 10:28:03 +02:00
Alvaro Fuentes af886f3673 [FIX] base: correctly apply implied groups
If one of the groups in `self` implies the group `implied_group` then
the rest won't be updated.

This also contradicts the way the settings are later checked (which is
correct) on
https://github.com/odoo/odoo/blob/f2c214e227db7c9ec2340ef87644f2f7c2e370c5/odoo/addons/base/models/res_config.py#L508

See 4f19f29a

opw-2832741
upg-356843

X-original-commit: 1754c744c8d00925d40c44742de3600389f7af47
Part-of: odoo/odoo#96928
2022-07-28 10:28:02 +02:00
Alvaro Fuentes 2ba68a266c [FIX] stock: traceback when there is no delveries for a lot
Fixes 38bfbed
We cannot create a `set` from `None`
```
   File "/home/odoo/src/odoo/15.0/addons/stock/models/stock_production_lot.py", line 225, in <listcomp>
    delivery_ids.update(*[set(delivery_by_lot.get(lot_id)) for lot_id in (producing_move_lines.produce_line_ids.lot_id - next_lots).ids])
 TypeError: 'NoneType' object is not iterable
```
Small optimization: no need to create a list that's immediately unpacked.

This error was detected during upgrades.
upg-360084

closes odoo/odoo#95398

X-original-commit: 1870ef4cf4c177846fce72325ff3f2fa97224417
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Alvaro Fuentes Suarez (afu) <afu@odoo.com>
2022-07-06 13:11:48 +02:00
Alvaro Fuentes d5f2fc2e37 [FIX] payment: fix misplaced sudo
On 02eba891cb8cd58985837090f2b60cf263bce065
we changed
https://github.com/odoo/odoo/blob/b5cf1ee3e21f2e60b8edd64f24c04c952fb7df3f/addons/payment/models/account_payment.py#L47
to
https://github.com/odoo/odoo/blob/02eba891cb8cd58985837090f2b60cf263bce065/addons/payment/models/account_payment.py#L47-L48
Effectively moving the place where `sudo` is called.

This causes issues during migration of some DBs
upg-328570

closes odoo/odoo#92651

X-original-commit: 90c321cc8bad04f7f094a221a39ca6f647944f5d
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
2022-06-01 16:26:32 +02:00
Alvaro Fuentes 45631cfcea [FIX] project: MemoryError on _compute_attached_docs_count
When there are multiple projects and many tasks the compute of
project.project.doc_count may raise a `MemoryError` on access to the
projects kanban view.

This issue may appear since the addition on 642fb2e6 of docs_count field
to the kanban view `view_project_kanban`.
https://github.com/odoo/odoo/blob/136808203545eb5d7056d941f3fc250f2871f95b/addons/project/views/project_views.xml#L613
This provokes too much information to be prefetched by the ORM, in
particular the `description` fields of the tasks which may be big (e.g.
contain embedded images).

This issue was observed during upg-101057

closes odoo/odoo#83997

X-original-commit: 6c207ed1027d9b39eecd19886932b17f1a79dccd
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
2022-02-04 16:54:04 +00:00
Alvaro Fuentes bc3a01b325 [FIX] maintenance: MemoryError on compute
When computing the todo fields of maintenance requests, we could get a
`MemoryError` since we are fetching more fields that we actually need.

Here we rework the way the compute is done in order to avoid too much
prefetch.

closes odoo/odoo#82662

X-original-commit: 510831013ba081edd83191a01d562485b6ceca38
Signed-off-by: Christophe Simonis <chs@odoo.com>
2022-01-12 18:24:48 +00:00
Alvaro Fuentes 1f163eed03 [FIX] maintenance: set noupdate for stages
It's useless to trigger the udpate of the stages during module (or whole
DB) upgrade if these stages do not change. It's been the same since at
least 12.0. Updating the stage triggers a series of computes that may
end up in MemoryError during upgrade.
https://github.com/odoo/odoo/blob/7b3b623cf3359ac1eea537177f7f963e81403a01/addons/maintenance/models/maintenance.py#L434-L441

closes odoo/odoo#82651

X-original-commit: 387bc337930e55511d336351db3ce3ddd80f524c
Signed-off-by: Christophe Simonis <chs@odoo.com>
2022-01-12 15:49:39 +00:00
Alvaro Fuentes 17bb0af7a8 [FIX] mail: check res_id!=0 when checking access rules
Although 0 is a valid value (integer), this has been (ab)used to signal
that a mail activity is not linked to any other record via res_id.

The issue is that when we have `0` as res_id value we get an error here
https://github.com/odoo/odoo/blob/158c0ae425b3be446d81c3a6f4387b2d9426d10e/addons/mail/models/mail_activity.py#L377
more specifically on
https://github.com/odoo/odoo/blob/158c0ae425b3be446d81c3a6f4387b2d9426d10e/odoo/models.py#L3603
with `AttributeError: 'int' object has no attribute 'origin'`

To avoid the issue, here we discard id `0` when checking the linked
records access rules.

On #81292 (targeting master, >15.1 at the moment of writing) a
constraint will be added to avoid `0` on `res_id`.

closes odoo/odoo#82281

X-original-commit: f96cec284a0714ae8eaa264d7adee503a96618d7
Signed-off-by: Christophe Simonis <chs@odoo.com>
2022-01-05 16:21:59 +00:00
Alvaro Fuentes c5ae057618 [FIX] base: in res.config.settings, field.related is a string
It used to be a tuple.
Cf: 1abe965b59

opw-2681777

closes odoo/odoo#81312

X-original-commit: aa74f51db7bf5a8ad1f4e309b6352df3c31037ec
Signed-off-by: Raphael Collet <rco@odoo.com>
2021-12-13 14:11:51 +00:00
Alvaro Fuentes 525f7f1407 [FIX] hr_work_entry: improve query and add indices
The query below
https://github.com/odoo/odoo/blob/81497125d8100c6bdd2dc30434232a88a419a3e3/addons/hr_work_entry/models/hr_work_entry.py#L92-L115
has bad performance without the bespoken indices on `date_start` and
`date_stop`. We can speed it up more with an index on `employee_id`.

This is not enough for DBs with many work entries (500K+), specially
during upgrades.

Here we optimize the query to take into account only the work entries
being modified.

This issue was observed during an upgrade saas~12.3->13.0 where the
payslip recomputation never ends due to the increased amount of hr work
entries created. Note how the first 1K payslips are processed in 1 hour
(~16 payslips per minute), while the latest 3 (before the upgrade
was killed) took 1 min.
```
2021-11-02 21:05:44,403 2229 INFO db_42897 odoo.modules.migration: module hr_payroll: Running migration [$saas~12.4.1.0] end-compute-amount
2021-11-02 21:06:44,577 2229 INFO db_42897 odoo.upgrade: [1.61%] 1120/69635 payslip processed in 0:01:00.036716 (total estimated time: 1:02:12.729213)
2021-11-02 21:07:44,602 2229 INFO db_42897 odoo.upgrade: [2.66%] 1853/69635 payslip processed in 0:02:00.062972 (total estimated time: 1:15:11.918540)
...
2021-11-05 09:59:46,565 2229 INFO db_42897 odoo.upgrade: [47.95%] 33390/69635 payslip processed in 2 days, 12:54:02.025479 (total estimated time: 5 days, 7:00:30.261882)
2021-11-05 10:01:04,990 2229 INFO db_42897 odoo.upgrade: [47.95%] 33393/69635 payslip processed in 2 days, 12:55:20.450549 (total estimated time: 5 days, 7:02:32.725840)
```

opw-2672031

closes odoo/odoo#80898

X-original-commit: 47b7a760c5788782c65136e529c8283fe5f0cce2
Signed-off-by: Nicolas Seinlet (nse) <nse@odoo.com>
2021-12-07 07:33:07 +00:00
Alvaro Fuentes 0e0fde5cc7 [FIX] stock: fix search default property for missing locs
It may happen that there is a property defined on some field that is not
the default property, but rather the property associated to a record.
For example
```
=> select id,name,company_id,fields_id,value_reference,res_id from ir_property where name like '%property_stock_inventory%'
+------+--------------------------+--------------+-------------+-------------------+----------------------+
| id   | name                     | company_id   | fields_id   | value_reference   | res_id               |
|------+--------------------------+--------------+-------------+-------------------+----------------------|
| 528  | property_stock_inventory | 1            | 4665        | <null>            | product.template,752 |
| 6    | property_stock_inventory | <null>       | 4665        | stock.location,5  | <null>               |
+------+--------------------------+--------------+-------------+-------------------+----------------------+
```
In this case the property with id=528 is not a default property since
res_id is not NULL. Alternatively the property id=6 is a default one.

The issue here is that when searching for the missing locations we do
not filter out the properties with res_id not NULL, thus we may get that
a company has the location define while in fact it doesn't. Following
the example above, this means that we incorrectly get property id=528 as
the one defining the location for the company id=1 here:
https://github.com/odoo/odoo/blob/c5c47da2e96fd5e37030c70d6bb1bae4c4047fa8/addons/stock/models/res_company.py#L107
This not only prevents the creation of the correct default property but
also the default locations
https://github.com/odoo/odoo/blob/c5c47da2e96fd5e37030c70d6bb1bae4c4047fa8/addons/stock/models/res_company.py#L36-L51

On this patch we fix the domain search for default property. This allows
for the correct creation of the default locations and associated
properties.

This issue was observed during upgrade 40921, where it prevents the
upgrade to 15.0

closes odoo/odoo#79000

X-original-commit: b9d98950826e7272b1df4f6f2467d1d2d14dcc64
Signed-off-by: Arnold Moyaux <arm@odoo.com>
2021-10-26 13:23:16 +00:00
Alvaro Fuentes 08ab5ddb88 [FIX] base: fix avatar_mixin seed for hsl
Some records have NULL create_date. In that case we get a traceback like
below.
```
 Traceback (most recent call last):
   ...
   File "/home/odoo/src/odoo/15.0/addons/mail/models/mail_thread.py", line 410, in _compute_field_value
    return super()._compute_field_value(field)
   File "/home/odoo/src/odoo/15.0/odoo/models.py", line 4249, in _compute_field_value
    getattr(self, field.compute)()
   File "/home/odoo/src/odoo/15.0/odoo/addons/base/models/res_partner.py", line 259, in _compute_avatar_128
    super()._compute_avatar_128()
   File "/home/odoo/src/odoo/15.0/odoo/addons/base/models/avatar_mixin.py", line 62, in _compute_avatar_128
    self._compute_avatar('avatar_128', 'image_128')
   File "/home/odoo/src/odoo/15.0/odoo/addons/base/models/res_partner.py", line 263, in _compute_avatar
    super(Partner, partners_with_internal_user)._compute_avatar(avatar_field, image_field)
   File "/home/odoo/src/odoo/15.0/odoo/addons/base/models/avatar_mixin.py", line 39, in _compute_avatar
    avatar = record._avatar_generate_svg()
   File "/home/odoo/src/odoo/15.0/odoo/addons/base/models/avatar_mixin.py", line 66, in _avatar_generate_svg
    bgcolor = get_hsl_from_seed(self[self._avatar_name_field] + str(self.create_date.timestamp()))
 AttributeError: 'bool' object has no attribute 'timestamp'
```
Observed during upgrade request 40906

closes odoo/odoo#78945

X-original-commit: 559d53fd2a0d437fae595dd4700f2607c8de81a8
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2021-10-25 15:50:58 +00:00
Alvaro Fuentes ad9c67a1e2 [FIX] purchase: fix MemoryError when there are lots of line_ids
It seems that this long dereference causes a MemoryError for accounts
with many associated line_ids
```
select count(*) from account_analytic_account a join account_analytic_line l on l.account_id = a.id join account_move_line ml on ml.id = l.move_id where a.id=7
+---------+
| count   |
|---------|
| 131672  |
+---------+
```
The solution we propose is to use search_read inverting the order of
dereferences.

Shortened Traceback:
```
 Traceback (most recent call last):
 ...
   File "/home/odoo/src/odoo/15.0/addons/mail/models/mail_thread.py", line 410, in _compute_field_value
    return super()._compute_field_value(field)
   File "/home/odoo/src/odoo/15.0/odoo/models.py", line 4249, in _compute_field_value
    getattr(self, field.compute)()
   File "/home/odoo/src/odoo/15.0/addons/purchase/models/analytic_account.py", line 15, in _compute_purchase_order_count
    account.purchase_order_count = len(account.line_ids.move_id.purchase_order_id)
...
   File "/home/odoo/src/odoo/15.0/odoo/api.py", line 893, in update
    field_cache.update(zip(records._ids, values))
 MemoryError
```

Observed during the upgrade of 41031

We can reproduce this pref issue locally.
On the menu Accounting > Configuration > Analytic Accounting > Analytic Accounts, with 1 million account moves
```
test_15.0=> select account_id,count(*) from account_analytic_line group by account_id
+--------------+---------+
| account_id   | count   |
|--------------+---------|
| 1            | 1000002 |
+--------------+---------+
```
We get (shortened):
```
2021-10-19 07:39:33,807 53565 INFO test_15.0 werkzeug: 127.0.0.1 - - [19/Oct/2021 07:39:33] "POST /longpolling/poll HTTP/1.1" 200 - 9 0.077 50.063
2021-10-19 07:39:33,888 53565 INFO test_15.0 werkzeug: 127.0.0.1 - - [19/Oct/2021 07:39:33] "POST /longpolling/im_status HTTP/1.1" 200 - 4 0.038 0.044
2021-10-19 07:40:05,916 53565 WARNING test_15.0 odoo.service.server: Thread <Thread(odoo.service.http.request.140269940897536, started 140269940897536)> virtual real time limit (178/120s) reached.
2021-10-19 07:40:05,921 53565 INFO test_15.0 odoo.service.server: Dumping stacktrace of limit exceeding threads before reloading
2021-10-19 07:40:06,296 53565 INFO test_15.0 odoo.tools.misc:
File: "/usr/lib/python3.8/threading.py", line 890, in _bootstrap
...
File: "/home/odoo/src/odoo/15.0/addons/mail/models/mail_thread.py", line 410, in _compute_field_value
  return super()._compute_field_value(field)
File: "/home/odoo/src/odoo/15.0/odoo/models.py", line 4249, in _compute_field_value
  getattr(self, field.compute)()
File: "/home/odoo/src/odoo/15.0/addons/purchase/models/analytic_account.py", line 15, in _compute_purchase_order_count
  account.purchase_order_count = len(account.line_ids.move_id.purchase_order_id)
File: "/home/odoo/src/odoo/15.0/odoo/fields.py", line 2605, in __get__
  return self.mapped(records)
File: "/home/odoo/src/odoo/15.0/odoo/fields.py", line 1176, in mapped
  self.__get__(first(remaining), type(remaining))
File: "/home/odoo/src/odoo/15.0/odoo/fields.py", line 2603, in __get__
  return super().__get__(records, owner)
File: "/home/odoo/src/odoo/15.0/odoo/fields.py", line 1081, in __get__
  recs = record._in_cache_without(self)
File: "/home/odoo/src/odoo/15.0/odoo/models.py", line 5901, in _in_cache_without
  return self.browse(ids)
File: "/home/odoo/src/odoo/15.0/odoo/models.py", line 5149, in browse
  ids = tuple(ids)
File: "/home/odoo/src/odoo/15.0/odoo/api.py", line 952, in get_missing_ids
  if record_id not in field_cache:
```

closes odoo/odoo#78615

X-original-commit: 6077c9358fe650bcdc23e8d6a9432f639fca1b40
Signed-off-by: Rémy Voet <ryv-odoo@users.noreply.github.com>
2021-10-19 12:02:25 +00:00
Alvaro Fuentes 433f0c15bf [FIX] sale_timesheet_margin: fix division by zero
If the denomirator is zero, we set the computed value to zero.

closes odoo/odoo#78522

X-original-commit: 2b0a5ce53aa55da056d6acd6461a56aea75611ce
Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
2021-10-18 10:22:02 +00:00
Alvaro Fuentes d766744b1c [FIX] base: fix ir_attachment read_group
When called with a `srt` as readgroup parameter we get a traceback.
Example:
`read_group([('partner_id', 'in', self.ids)], 'partner_id', 'partner_id')`
TB:
```
 Traceback (most recent call last):
   File "/home/odoo/src/odoo/14.0/odoo/tools/safe_eval.py", line 330, in safe_eval
    return unsafe_eval(c, globals_dict, locals_dict)
   File "", line 2, in <module>
   File "/home/odoo/src/odoo/14.0/odoo/addons/base/models/ir_attachment.py", line 420, in read_group
    if any('(' in field for field in fields + groupby):
 TypeError: can only concatenate list (not "str") to list
 ```

 Observed on the upgrade request 22627.

closes odoo/odoo#75416

X-original-commit: 8e7990dd5c069f7b0dba9f3d27f620f0fcad5441
Signed-off-by: Christophe Simonis <chs@odoo.com>
2021-08-20 18:52:19 +00:00
Alvaro Fuentes aa4fad64ce [FIX] web: fix web_read_group total groups count
Fetching all the groups from the DB causes MemoryError on some DBs
Example Accounting > Accounting > Journals > Miscellaneous menu:
```
 Traceback (most recent call last):
   File "/tmp/tmpbnah9jtp/migrations/base/tests/test_mock_crawl.py", line 176, in crawl_menu
    self.mock_action(action_vals)
   File "/tmp/tmpbnah9jtp/migrations/base/tests/test_mock_crawl.py", line 267, in mock_action
    mock_method(model, view, fields_list, domain, group_by)
   File "/tmp/tmpbnah9jtp/migrations/base/tests/test_mock_crawl.py", line 380, in mock_view_tree
    self.mock_web_read_group(model, view, domain, group_by, fields_list, limit_group=5)
   File "/tmp/tmpbnah9jtp/migrations/base/tests/test_mock_crawl.py", line 425, in mock_web_read_group
    data = model.web_read_group(domain, fields_list, group_by, limit=limit)["groups"]
   File "/home/odoo/src/odoo/14.0/addons/web/models/models.py", line 96, in web_read_group
    all_groups = self.read_group(domain, ['display_name'], groupby, lazy=True)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 2248, in read_group
    result = self._read_group_raw(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 2387, in _read_group_raw
    result = [self._read_group_format_result(d, annotated_groupbys, groupby, domain) for d in data]
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 2387, in <listcomp>
    result = [self._read_group_format_result(d, annotated_groupbys, groupby, domain) for d in data]
 MemoryError
```

This issue was observed during the upgrade requests upg-18830, target
14.0; and upg-61934 (legacy), target 13.0

The issue can be reproduced on a clean DB with just account_accountant
installed and ~2 millions account moves on a Misc journal.

closes odoo/odoo#73855

X-original-commit: a9b3d9cf9bfd2bf4c9b0904059f1606ad6e04ee4
Signed-off-by: Christophe Simonis <chs@odoo.com>
2021-07-16 11:29:29 +00:00
Alvaro Fuentes d25b4b020d [FIX] account: fix tuple domain
Domains must be lists on calls to `_where_calc`.
```
 Traceback (most recent call last):
   File "/tmp/tmpjmcn3gby/migrations/base/tests/test_mock_crawl.py", line 162, in crawl_menu
    self.mock_action(action_vals)
   File "/tmp/tmpjmcn3gby/migrations/base/tests/test_mock_crawl.py", line 253, in mock_action
    mock_method(model, view, fields_list, domain, group_by)
   File "/tmp/tmpjmcn3gby/migrations/base/tests/test_mock_crawl.py", line 366, in mock_view_tree
    self.mock_web_read_group(model, view, domain, group_by, fields_list, limit_group=5)
   File "/tmp/tmpjmcn3gby/migrations/base/tests/test_mock_crawl.py", line 442, in mock_web_read_group
    self.mock_web_search_read(model, view, [group["__domain"]], fields_list)
   File "/tmp/tmpjmcn3gby/migrations/base/tests/test_mock_crawl.py", line 402, in mock_web_search_read
    data = model.search_read(domain=domain, fields=fields_list, limit=80)
   File "/home/odoo/src/odoo/14.0/addons/account/models/account_move.py", line 3645, in search_read
    return super(AccountMoveLine, self.with_context(domain_cumulated_balance=to_tuple(domain or []), order_cumulated_balance=order)).search_read(domain, fields, offset, limit, order)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 4839, in search_read
    result = records.read(fields)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 3020, in read
    return self._read_format(fnames=fields, load=load)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 3040, in _read_format
    vals[name] = convert(record[name], record, use_name_get)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 5666, in __getitem__
    return self._fields[key].__get__(self, type(self))
   File "/home/odoo/src/odoo/14.0/odoo/fields.py", line 1019, in __get__
    self.compute_value(recs)
   File "/home/odoo/src/odoo/14.0/odoo/fields.py", line 1175, in compute_value
    records._compute_field_value(self)
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 4061, in _compute_field_value
    getattr(self, field.compute)()
   File "/home/odoo/src/odoo/14.0/addons/account/models/account_move.py", line 3655, in _compute_cumulated_balance
    query = self._where_calc(self.env.context.get('domain_cumulated_balance'))
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 4247, in _where_calc
    domain = [(self._active_name, '=', 1)] + domain
 TypeError: can only concatenate list (not "tuple") to list
```

Observed on upgrade request 11722
Ref 9d28c71a71 since saas-13.2

closes odoo/odoo#73522

X-original-commit: e24295da8436b4d24cd03f6ac1f22e86465f950d
Signed-off-by: Christophe Simonis <chs@odoo.com>
2021-07-09 20:50:24 +00:00
Alvaro FuentesandChristophe Simonis 6597b8c971 [FIX] core: fix _get_default_calendar_view
Due to odoo/odoo#51075 it's an error to assign the `_date_name` field on
an empty recordset.

```
 Traceback (most recent call last):
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 1582, in _fields_view_get
    arch_etree = getattr(self, '_get_default_%s_view' % view_type)()
   File "/home/odoo/src/odoo/14.0/odoo/models.py", line 1495, in _get_default_calendar_view
    self._date_name = dt
 AttributeError: 'project.phase' object attribute '_date_name' is read-only
```

Issue observed on upgrade requests 2615 and 3121.

closes odoo/odoo#73401

X-original-commit: 1bbe88796a5b03ab1ab2faec1f0fe4f735fcb485
Signed-off-by: Christophe Simonis <chs@odoo.com>
Co-authored-by: Christophe Simonis <chs@odoo.com>
2021-07-07 19:18:12 +00:00
Alvaro Fuentes 003eb3b89d [FIX] core/expression: fix 'not in' for translated fields
Domain terms of the form `('field', 'not in', [...])` generate incorrect
queries for translated fields, example (model `res.country`, field `name`):
```
psycopg2.errors.SyntaxError: syntax error at or near "ARRAY"
LINE 1: ...M "res_country" WHERE "res_country"."name" not in ARRAY['No ...
```
The root cause is that the right part of the term is not converted to
tuple.

Observed during the upgrade request 16639
opw-2525553

closes odoo/odoo#73030

X-original-commit: 7c4db97e21f74a429e56f6cae4d4786ee74f7e22
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-06-30 18:18:56 +00:00
Alvaro Fuentes 4de85d4306 [FIX] sale_timesheet: fix _compute_warning_employee_rate
On account analytic lines, employee_id can be null.
https://github.com/odoo/odoo/blob/c63af09774414a004ef34644b4f38b4fdb1d12bd/addons/hr_timesheet/models/hr_timesheet.py#L48

```
Traceback (most recent call last):
  File "/tmp/tmpowipzc_d/migrations/base/tests/test_mock_crawl.py", line 155, in crawl_menu
    self.mock_action(action_vals)
  File "/tmp/tmpowipzc_d/migrations/base/tests/test_mock_crawl.py", line 245, in mock_action
    mock_method(model, view, fields_list, domain, group_by)
  File "/tmp/tmpowipzc_d/migrations/base/tests/test_mock_crawl.py", line 335, in mock_view_kanban
    self.mock_web_search_read(model, view, [domain], fields_list)
  File "/tmp/tmpowipzc_d/migrations/base/tests/test_mock_crawl.py", line 394, in mock_web_search_read
    data = model.search_read(domain=domain, fields=fields_list, limit=80)
  File "/home/odoo/src/odoo/14.0/odoo/models.py", line 4839, in search_read
    result = records.read(fields)
  File "/home/odoo/src/odoo/14.0/odoo/models.py", line 3020, in read
    return self._read_format(fnames=fields, load=load)
  File "/home/odoo/src/odoo/14.0/odoo/models.py", line 3040, in _read_format
    vals[name] = convert(record[name], record, use_name_get)
  File "/home/odoo/src/odoo/14.0/odoo/models.py", line 5666, in __getitem__
    return self._fields[key].__get__(self, type(self))
  File "/home/odoo/src/odoo/14.0/odoo/fields.py", line 1019, in __get__
    self.compute_value(recs)
  File "/home/odoo/src/odoo/14.0/odoo/fields.py", line 1175, in compute_value
    records._compute_field_value(self)
  File "/home/odoo/src/odoo/14.0/addons/mail/models/mail_thread.py", line 410, in _compute_field_value
    return super()._compute_field_value(field)
  File "/home/odoo/src/odoo/14.0/odoo/models.py", line 4061, in _compute_field_value
    getattr(self, field.compute)()
  File "/home/odoo/src/odoo/14.0/addons/sale_timesheet/models/project.py", line 90, in _compute_warning_employee_rate
    dict_project_employee[line['project_id'][0]] += [line['employee_id'][0]]
TypeError: 'bool' object is not subscriptable
```

```
❯ psql test_14 -c '\d account_analytic_line' | grep employee_id
 employee_id            | integer                     |           |          |
    "account_analytic_line_employee_id_fkey" FOREIGN KEY (employee_id) REFERENCES hr_employee(id) ON DELETE SET NULL
```

Observed on upgrade request 16289
opw-2525553

Steps to reproduce on runbot (or local db with -i sale_timesheet and
deoma data)
1. Select Project > Office Design
2. Change project settings:
  Settings tab > Billable=True
  Invoicing tab > Invoice Tasks to=A unique customer
                > Pricing=Employee rate
3. Save
4. Delete Employees > Eli Lambert
5. Open Project main menu -> Traceback

closes odoo/odoo#72081

X-original-commit: 71c3897a07918679717d57f65eeadb34b54cdcbd
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
2021-06-11 16:16:37 +00:00
Alvaro FuentesandChristophe Simonis 0a96e7b90c [FIX] core: correct imports from odoo.addons.base.maintenance.migrations
This legacy package was supposed to be an alias to `odoo.upgrade`.
However, depending on how your import its sub-packages (and in which
order), we were ending with the module being loaded multiple times,
breaking the expectation of a singleton.

```python
In [1]: from odoo.addons.base.maintenance.migrations import util as m1

In [2]: import odoo.addons.base.maintenance.migrations.util as m2

In [3]: m1
Out[3]: <module 'odoo.upgrade.util' from '/Users/chs/devel/odoo/odoo/stable/odoo/addons/base/maintenance/migrations/util.py'>

In [4]: m2
Out[4]: <module 'odoo.addons.base.maintenance.migrations.util' from '/Users/chs/devel/odoo/odoo/stable/odoo/addons/base/maintenance/migrations/util.py'>

In [5]: from odoo.addons.base.maintenance.migrations import util as m3

In [6]: m3
Out[6]: <module 'odoo.addons.base.maintenance.migrations.util' from '/Users/chs/devel/odoo/odoo/stable/odoo/addons/base/maintenance/migrations/util.py'>

In [7]: m2 == m3
Out[7]: True

In [8]: m1 == m3
Out[8]: False

In [9]:
```

Now, with this import hook, we ensure that the modules imported from
`odoo.addons.base.maintenance.migrations` are aliases to ones imported
from `odoo.upgrade`.

```python
In [1]: import odoo.addons.base.maintenance.migrations.util as m2

In [2]: m2.__name__
Out[2]: 'odoo.upgrade.util'
```

closes odoo/odoo#71351

X-original-commit: 0d0458a0f370f872caacac26361f2c4730c2cbba
Signed-off-by: Christophe Simonis <chs@odoo.com>
Co-authored-by: Christophe Simonis <chs@odoo.com>
2021-05-27 15:41:24 +00:00
Alvaro Fuentes 14036869c7 [FIX] core: fix filtered_domain for hierarchical terms
The method filtered_domain() is broken for domains with hierarchical
terms ('child_of'/'parent_of').

To see *one* of the ways the implementation is broken, let `A` be a
model with `parent_id` pointing to `A`, and `a1` a record of model `A`
without parent (`a1.parent_id` is `False`), then this fails:

    assert a1 in a1.filtered_domain([("parent_id", "child_of", a1.id)])

The reason it fails is that on
https://github.com/odoo/odoo/blob/f5519586d214a9b34ad24683a7f97c47802a3bad/odoo/models.py#L5377-L5380
`data` is empty since `a1` has no parent, thus
https://github.com/odoo/odoo/blob/f5519586d214a9b34ad24683a7f97c47802a3bad/odoo/models.py#L5403-L5404
fails, therefore the result of `filtered_domain` is empty.

Note: the implementation of the hierarchical operators is full of quirks
that are hard to emulate otherwise than by reusing the original code.
As a consequence, the current implementation may be broken in more than
one way.

Let's see another way the implementation is broken: let `B` be a model
without a `parent_id` field and with a `friend_id` field pointing
to `B`, and let `b1` be a record of model `B`.  Then

    b1.filtered_domain([("friend_id", "child_of", b1.id)])

throws an exception of the form shown below:

    ValueError: Invalid field 'parent_id' in leaf "<osv.ExtendedLeaf: ('parent_id', 'child_of', 1) ...

Meanwhile the following code is still valid and returs b1:

    B.search([("friend_id", "child_of", b1.id)])

closes odoo/odoo#71237

X-original-commit: e7a5ba95d8b7df5bbf545ef8afe0a1f5d0f70272
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-05-25 18:08:42 +00:00
Alvaro Fuentes 23afd3642e [FIX] base/ir_model: fix materialized views columns listing
When there is a materialized view that has not been populated any select
on it will fail.

Example of traceback:
```
Traceback (most recent call last):
  File "/home/odoo/src/odoo/12.0/odoo/service/server.py", line 1162, in preload_registries
    registry = Registry.new(dbname, update_module=update_module)
  File "/home/odoo/src/odoo/12.0/odoo/modules/registry.py", line 86, in new
    odoo.modules.load_modules(registry._db, force_demo, status, update_module)
  File "/home/odoo/src/odoo/12.0/odoo/modules/loading.py", line 367, in load_modules
    registry.setup_models(cr)
  File "/home/odoo/src/odoo/12.0/odoo/modules/registry.py", line 262, in setup_models
    env['ir.model']._add_manual_models()
  File "/home/odoo/src/odoo/12.0/odoo/addons/base/models/ir_model.py", line 321, in _add_manual_models
    cr.execute('SELECT * FROM %s LIMIT 0' % Model._table)
  File "/home/odoo/src/odoo/12.0/odoo/sql_db.py", line 148, in wrapper
    return f(self, *args, **kwargs)
  File "/home/odoo/src/odoo/12.0/odoo/sql_db.py", line 225, in execute
    res = self._obj.execute(query, params)
psycopg2.errors.ObjectNotInPrerequisiteState: materialized view "x_bi_sql_view_report_copy" has not been populated
HINT:  Use the REFRESH MATERIALIZED VIEW command.
```

Several upgrade requests have or had had this error which has been
solved with specific scripts.

Related to #40930

closes odoo/odoo#71008

X-original-commit: b208570ce8399bc6d3e4a8ba02eef6558e0a6ccc
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-05-18 18:51:19 +00:00
Alvaro Fuentes 05aab3552c [FIX] core/expression: fix distribute_not over thruty leafs
A domain with a negated thruty leaf raises an exception here
https://github.com/odoo/odoo/blob/835197e48fbbee1c8ac35d52287537fa6f0bdd36/odoo/osv/expression.py#L614
due to
https://github.com/odoo/odoo/blob/835197e48fbbee1c8ac35d52287537fa6f0bdd36/odoo/osv/expression.py#L670
and the fact that `FALSE_LEAF != (1, "!=", 1)` and `TRUE_LEAF != (0, "!=", 1)`

Current wrong behaviour:
```
>>> distribute_not(['!', TRUE_LEAF])
[(1, '!=', 1)]
>>> is_leaf((1, '!=', 1))
False
```

This issue was noticed when adapting domains for fields that have been
removed during migration. Example (extract of) traceback:
```
Traceback (most recent call last):
  File "/home/odoo/src/odoo/13.0/odoo/http.py", line 624, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  ...
  File "/home/odoo/src/odoo/13.0/odoo/osv/expression.py", line 677, in __init__
    self.parse()
  File "/home/odoo/src/odoo/13.0/odoo/osv/expression.py", line 814, in parse
    self.stack = [ExtendedLeaf(leaf, self.root_model) for leaf in self.expression]
  File "/home/odoo/src/odoo/13.0/odoo/osv/expression.py", line 814, in <listcomp>
    self.stack = [ExtendedLeaf(leaf, self.root_model) for leaf in self.expression]
  File "/home/odoo/src/odoo/13.0/odoo/osv/expression.py", line 562, in __init__
    self.check_leaf(internal)
  File "/home/odoo/src/odoo/13.0/odoo/osv/expression.py", line 618, in check_leaf
    raise ValueError("Invalid leaf %s" % str(self.leaf))
ValueError: Invalid leaf (0, '!=', 1)
```

closes odoo/odoo#68665

X-original-commit: e20c23658d15a135e5f35b0e8dec6e3202cecaab
Signed-off-by: Christophe Simonis <chs@odoo.com>
2021-04-01 17:14:16 +00:00
Alvaro Fuentes 8aa4f42442 [IMP] tests: add test_sequence order for tests
We have some tests in odoo/upgrade that are sensitive to the order on
which they are executed. Specifically: IntegrityCase tests need to be
run after all UpgradeCase tests across all Odoo modules.

To support this we implemented a sorting mechanism for tests based on
the test_sequence class attribute. This is intended to be used by meta
cases, not by individual tests.

closes odoo/odoo#66521

Related: odoo/upgrade#2184
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2021-02-19 12:51:00 +00:00