Friday, August 11, 2023
15 changes · master
Enhancements to existing features
This update harmonizes how hierarchy levels are applied in localized financial and tax reports across many countries. It helps reports display their sections more consistently, especially in localizations with non-standard report structures.
Original PR description
Added the improvements brought by https://github.com/odoo/enterprise/pull/43885 to localisations financial report when they don't follow the usual section distribution. task-3452382
Country and state names can now be translated for customer-facing experiences such as eCommerce checkout and PDF reports. This helps businesses operating in multilingual regions show place names in the customer's language, improving clarity and localization.
Original PR description
Country states are used in multiple customer facing flows, most notably eCommerce and pdf reports. Quite a few countries are multi-lingual and might have localized names for country states (e.g. Namur/Namen in Belgium, Nouveau-Brunswick/New-Brunswick in Canada, Fribourg/Freiburg/Friburgo/Friburg in Switwerland, etc.). This commit makes it possible to translate these names for better customer-facing experiences. Task-3285734
Odoo now supports clearer and more flexible search rules for records linked to other records, such as customers, projects, sales, and HR data. This improves consistency between different ways of filtering data and helps business rules return more reliable results.
Subtasks now automatically receive the same milestone as their parent task when appropriate, helping teams keep related work aligned. This reduces manual updates and makes project progress tracking more consistent.
Original PR description
As sub-tasks are a sub-set of a task that should logically be completed for the parent task to be completed, it would make sense for the sub-tasks to share the same milestone as their parent task by default. The milestone of a parent task is automatically set to its subtasks if: - The subtask has no milestone set - They belong to the same project or the subtask has no project set task-3450281
Financial reports for multiple country localizations now use a more consistent hierarchy and section structure. This makes localized balance sheets, profit and loss statements, and tax reports easier to read and compare across regions.
Original PR description
Added the improvements brought by https://github.com/odoo/enterprise/pull/43885 to localisations financial report when they don't follow the usual section distribution. task-3452382
Marketing Automation now tracks whether an activity has never been synced using a clear status field instead of relying on timing comparisons. This reduces edge-case synchronization errors when campaigns and activities are created or updated very close together.
Original PR description
Currently the marketing automation app distinguishes new marketing activities based on the `last_sync_date` (by comparing it to the creation date). This however, introduces some race conditions in…
Currently the marketing automation app distinguishes new marketing activities based on the `last_sync_date` (by comparing it to the creation date). This however, introduces some race conditions in certain edge cases. These edge cases occur because of two reasons: 1) The `create_date` is computed using the sql `now()` function which uses the transaction timestamp. When creating new activities after synchronizing a campaign in the same transaction, this can be problematic. 2) The `last_sync_date` is computed in python land, by the static `now()` method on the odoo `Datetime` field. This method truncates milliseconds. When creating activities and campaigns in the same transaction this yields nondeterministic behavior: the second hand of the clock might tick in between the creation of the campaign and the computation of `last_sync_date`. As a consequence it is better to be explicit about the state of the marketing activity. This commit introduces an extra field on the marketing activity model to do exactly this, allowing a proper forward port of the currently unmerged marketing automation fixes. This is needed as a separate commit, because the new field can no longer be introduced after the freeze for odoo version 16. opw-2643368
Subscription renewals now carry the freeze plan setting correctly based on whether a commission plan is assigned. This helps sales teams avoid incorrect commission behavior on renewed quotations and reduces manual corrections.
Original PR description
Description of the issue: Before this commit if freeze plan option is enabled in subscription but it remains disable during renewal of quotation IMP: After this commit freeze plan property value will true after renewal if commission_plan have some value and if commission_plan have no value then freeze plan property will becomes false after renewal even its value true. task-3397824
Resolved issues and error corrections
Code cleanup and technical improvements
This change moves Odoo's interface templates from the older QWeb rendering system to the newer Owl rendering approach. It is mainly an internal modernization that should improve consistency and maintainability across many apps without intentionally changing business workflows.
Original PR description
The aim of this PR, is to remove qweb and use owl to render all the templates. task~3443861
Original PR description
This PR aims to improve the correctness and expressivity of domains including conditions on relational fields. The proposed implementation allows a new syntax where conditions on relational fields…
This PR aims to improve the correctness and expressivity of domains including conditions on relational fields. The proposed implementation allows a new syntax where conditions on relational fields can be expressed in terms of a domain on the comodel using a subquery operator. Subquery operators include `any` and `all` (respectively expressing the condition that at least one or all related records must meet the conditions in the domain) and their logical inverses `not any` and `not all`. Some examples:
```python
# These can be expressed using the old syntax (using search)
[('x2many_ids', 'any', [('field', '=', value)])]
[('x2many_ids', 'not all', [('field', '=', value)])]
[('x2many_ids', 'any', ['|', ('active', '=', True), ('visible', '=', True)])]
# These could not previously be expressed (using search)
[('x2many_ids', 'all', [('field', '=', value)])]
[('x2many_ids', 'not any', [('field', '=', value)])]
[('x2many_ids', 'any', ['&', ('active', '=', True), ('visible', '=', True)])]
[('x2many_ids', 'all', ['|', ('active', '=', True), ('visible', '=', True)])]
```
The new implementation can be considered more correct because of the clearer semantics, but also because of a number of inconsistencies that existed between the `search` and `filtered_domain` implementations:
1) When using the logical not on a one2many or a many2many leaf. In general `filtered_domain` will adhere to commonly accepted logical not semantics (any record not matched by the original leaf will match the inverted one) while the orm `search` does not. This happens because the orm transforms inverted leafs by negating the operator inside the leaf. This does not generally work when multiple values can match the condition.
2) Using negative operators. A similar inconsistency is caused by the logic used by the `filtered_domain` method. Negative operators such as `!=` and `not in` are implemented by inverting the results of their positive counterparts (any record is matched by the `filtered_domain` method if it is not matched by the corresponding positive operator). Approximately, the positive operators can be used for matching any related record, while for the negative ones all related records have to meet the condition.
Additionally, when both these situations occur together for the same leaf, the inconsistency is lifted. However, semantically the results could still be considered wrong. Using the equals operator as an example, the current search semantics can be summarized as follows:
For the orm `search` method:
* `[('x2many_ids.field', '=', value)]` -> any =
* `[('x2many_ids.field', '!=', value)]` -> any !=
* `['!', ('x2many_ids.field', '=', value)]` -> any !=
* `['!', ('x2many_ids.field', '!=', value)]` -> any =
For the python side `filtered_domain` method:
* `[('x2many_ids.field', '=', value)]` -> any =
* `[('x2many_ids.field', '!=', value)]` -> all !=
* `['!', ('x2many_ids.field', '=', value)]` -> all !=
* `['!', ('x2many_ids.field', '!=', value)]` -> any =
Where any and all follow their traditional (python) semantics. Expressing the condition in terms of a nested field is necessary for the inconsistency to occur. These observations hold for fields `field` of any type: this means it also holds for cases where `field` is a relational field (note that `value` should not be `False` or `[]`, these cases are handled separately).
3) Note that, as a consequence of the above, there also exists a self-contradiction in the handling of x2many fields by the `search` method. This happens because the `search` method adheres to the same semantics as the `filtered_domain` method for conditions on non-nested fields. Again, for the `search` method, we get:
* `[('x2many_ids', '!=', value)]` -> all !=
* `[('x2many_ids.nested_x2many_ids', '!=', value)]` -> any !=
4) A less severe inconsistency occurs when specifying conditions on one2many or many2many fields that use a comodel domain as part of their definition. When using search this domain is ignored while it is taken into consideration when using `filtered_domain`.This change prevents users from saving or printing manually created reports that point to templates that do not exist. It also ensures report templates are loaded before report actions, reducing unexpected print failures across many Odoo apps.
Original PR description
*: account, account_test, hr, hr_skills, l10n_ch, l10n_cn, l10n_fr_pos_cert, mrp, point_of_sale, pos_self_order, product, purchase, purchase_requisition, repair, stock, stock_picking_batch,…
*: account, account_test, hr, hr_skills, l10n_ch, l10n_cn, l10n_fr_pos_cert, mrp, point_of_sale, pos_self_order, product, purchase, purchase_requisition, repair, stock, stock_picking_batch, test_event_full, base
When the user manually creates the report action, configures the non-exists report view template, and tries to print the report, an "Invalid report template id" trace back will be generated.
Steps to produce:
- Install any module, e.g., sale_management.
- Settings > Technical > Actions > Reports
- Create a new record and fill out the required details. Set the 'Template Name' as 'abcd' or 'abcd.xyz', the 'Model Name' as 'sale.order, and the 'Action Name' as 'test report'.
- Click on the "Add to the 'Print' menu" button.
- Sales > Orders > Orders
- Select any report and print the 'test report, then traceback will be generated.
Error:
External ID not found in the system: base.elcom_report_document_user_equipments
This PR check, when the user manually configures the report action at that time, raises the validation error message if the report template does not exist in the views and also loads the report template views before the report action views.
Sentry Traceback:
```ValueError: External ID not found in the system: base.elcom_report_document_user_equipments
File "addons/web/controllers/report.py", line 113, in report_download
response = self.report_routes(reportname, docids=docids, converter=converter, context=context)
File "odoo/http.py", line 716, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "addons/web/controllers/report.py", line 42, in report_routes
pdf = report.with_context(context)._render_qweb_pdf(reportname, docids, data=data)[0]
File "odoo/addons/base/models/ir_actions_report.py", line 810, in _render_qweb_pdf
collected_streams = self._render_qweb_pdf_prepare_streams(report_ref, data, res_ids=res_ids)
File "odoo/addons/base/models/ir_actions_report.py", line 711, in _render_qweb_pdf_prepare_streams
html = self.with_context(**additional_context)._render_qweb_html(report_ref, res_ids_wo_stream, data=data)[0]
File "odoo/addons/base/models/ir_actions_report.py", line 887, in _render_qweb_html
return self._render_template(report.report_name, data), 'html'
File "odoo/addons/base/models/ir_actions_report.py", line 626, in _render_template
return view_obj._render_template(template, values).encode()
File "odoo/addons/base/models/ir_ui_view.py", line 2164, in _render_template
return self.env['ir.qweb']._render(template, values)
File "odoo/tools/profiler.py", line 292, in _tracked_method_render
return method_render(self, template, values, **options)
File "odoo/addons/base/models/ir_qweb.py", line 587, in _render
rendering = render_template(irQweb, values)
File "<None>", line 5, in not_found_template
```
Sentry-4293751777
Enterprise: https://github.com/odoo/enterprise/pull/43908This fixes a form behavior where choosing an action, such as duplicate, could still run after a failed save and cause a crash. Users will now see the save error without the requested action continuing, preventing confusing follow-up failures and protecting unsaved work.
Original PR description
Before this commit, in the form view, clicking on an action in the menu action executed the action even though the record save had failed.
Expected behaviour:
When you click on an action, you want to save the record and execute the action if the record was saved without error.
How to reproduce:
- Go to a form view
- Create a new record
- Edit a field to ensure that the save returns an error
- Click on an action in the action menu (for example duplicate)
- The "Oh Snap" dialog opens
- Click on "Discard
Before this commit:
The button action code executes and displays a crash
After this commit:
The button action code does not execute
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fixes cases where closing a related-record popup with the X button could accidentally keep unsaved changes. It also restores survey answer visibility after a question is discarded and reopened, helping users trust that discard actions behave consistently.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix restores the ability to delete tax repartition lines without triggering an error. It prevents an accounting setup issue that could block users from updating tax configurations when needed.
Original PR description
Problem --------- When deleting a tax repartition line, an error occurred. When popping the modified values during deletion, only two values were present in the modified values. Thus, unpacking to 3 variables resulted in an error: `v` did not exist. Objective --------- Make repartition lines deletable again. Solution --------- Instead of popping 3 values for every command, we pop 1 stored as a list. We access the relevant elements using the index when necessary. task-xxxxxxx --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo now honors Google Calendar settings that prevent guests from editing events. This avoids duplicate calendar entries and incorrect attendee lists when guests try to update events they are not allowed to modify.
Original PR description
Before this commit, the permission defined in Google Calendar of editing events by guests was always set in Odoo Calendar as 'True', even though there was also the 'False' option. This way, creating an event that didn't accept being edited by guests in Google and then updating it in Odoo by a guest was creating duplicates in Odoo Calendar and wrong lists of attendees. After this commit, the permission of guests modifying the event is taken into account in Odoo Calendar. If a guest updates an event that doesn't allow updates, a warning is shown forbidding the update and the reason explained. Task-id: 3276829
This update prevents users from reaching a technical error when a manually configured report points to a template that does not exist. It adds clearer validation and ensures report templates are loaded before report actions, improving reliability across payroll, localization, payments, manufacturing, quality, and signing features.
Original PR description
*: account_batch_payment, account_sepa_direct_debit, hr_payroll, l10n_be_hr_payroll, l10n_be_reports, l10n_ca_check_printing, l10n_in_hr_payroll, l10n_ke_hr_payroll, l10n_lt_hr_payroll,…
*: account_batch_payment, account_sepa_direct_debit, hr_payroll, l10n_be_hr_payroll, l10n_be_reports, l10n_ca_check_printing, l10n_in_hr_payroll, l10n_ke_hr_payroll, l10n_lt_hr_payroll, l10n_lu_hr_payroll, l10n_lu_reports_annual_vat_2023, l10n_mx_edi, l10n_mx_hr_payroll, l10n_nl_hr_payroll, l10n_pl_hr_payroll, l10n_sk_hr_payroll, l10n_us_check_printing, mrp_account_enterprise, quality_control, sign
When the user manually creates the report action, configures the non-exists report view template, and tries to print the report, an "Invalid report template id" trace back will be generated.
Steps to produce:
- Install any module, e.g., sale_management.
- Settings > Technical > Actions > Reports
- Create a new record and fill out the required details. Set the 'Template Name' as 'abcd' or 'abcd.xyz', the 'Model Name' as 'sale.order, and the 'Action Name' as 'test report'.
- Click on the "Add to the 'Print' menu" button.
- Sales > Orders > Orders
- Select any report and print the 'test report, then traceback will be generated.
Error:
External ID not found in the system: base.elcom_report_document_user_equipments
This PR check, when the user manually configures the report action at that time, raises the validation error message if the report template does not exist in the views and also loads the report template views before the report action views.
Sentry Traceback:
```ValueError: External ID not found in the system: base.elcom_report_document_user_equipments
File "addons/web/controllers/report.py", line 113, in report_download
response = self.report_routes(reportname, docids=docids, converter=converter, context=context)
File "odoo/http.py", line 716, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "addons/web/controllers/report.py", line 42, in report_routes
pdf = report.with_context(context)._render_qweb_pdf(reportname, docids, data=data)[0]
File "odoo/addons/base/models/ir_actions_report.py", line 810, in _render_qweb_pdf
collected_streams = self._render_qweb_pdf_prepare_streams(report_ref, data, res_ids=res_ids)
File "odoo/addons/base/models/ir_actions_report.py", line 711, in _render_qweb_pdf_prepare_streams
html = self.with_context(**additional_context)._render_qweb_html(report_ref, res_ids_wo_stream, data=data)[0]
File "odoo/addons/base/models/ir_actions_report.py", line 887, in _render_qweb_html
return self._render_template(report.report_name, data), 'html'
File "odoo/addons/base/models/ir_actions_report.py", line 626, in _render_template
return view_obj._render_template(template, values).encode()
File "odoo/addons/base/models/ir_ui_view.py", line 2164, in _render_template
return self.env['ir.qweb']._render(template, values)
File "odoo/tools/profiler.py", line 292, in _tracked_method_render
return method_render(self, template, values, **options)
File "odoo/addons/base/models/ir_qweb.py", line 587, in _render
rendering = render_template(irQweb, values)
File "<None>", line 5, in not_found_template
```
Sentry-4293751777
Community: https://github.com/odoo/odoo/pull/128039Odoo’s web templates have been updated to use the newer Owl rendering system instead of the older QWeb approach. This is mainly an internal modernization that improves consistency and maintainability across accounting, website sales, assets, consolidation, and related screens without introducing a new business feature.
Original PR description
The aim of this PR, is to remove qweb and use owl to render all the templates. task~3443861