Daily updates from Odoo
Wednesday, August 13, 2025
130 changes
49 changes
Resolved issues and error corrections
Employees assigned to recurring tasks in private projects can now mark them as done without receiving an access error. This keeps private project permissions intact while allowing normal task completion workflows to proceed.
Original PR description
to reproduce: ============= - create a private project and a recurrent task in it - assign the task to an employee - log in as the employee - mark the task as done - the task should be closed but it is not and the employee gets an error Problem: ======== while changing the state of a recurrent task, we need to read the project which is not allowed for this employee since the project is private. Solution: ======== we need to use sudo() to read the project in this case. opw-5012231 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222671
This fix prevents text areas from appearing in multiple live chat tabs at the same time during tests. It also corrects which field is checked for synchronized values, helping ensure live chat settings behave reliably.
Original PR description
Fix the unexpected behavior that the textareas in different tabs were both rendered by specifying the tab used in blur event. This commit also fixes the wrong target chosen for checking the sync value. runbot-230896 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Restoring an older task description from history now keeps the information needed to continue saving later edits. This prevents users from seeing an incorrect history-related error after applying a previous version and then updating the task again.
Original PR description
Problem: When applying a specific version from history in `task.description`, then updating and saving it, an error appears stating the content was saved from a different history model. Cause: When inserting versioned content, the required `data-last-history-steps` attribute is not included. Solution: Ensure the latest `data-last-history-steps` is added when restoring a version. Steps to reproduce: - Open Project > any task - Change the description - Save - Open version history and apply any version - Update the description - Save - Error appears opw-4829553 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216370
This fixes an issue that could prevent the Marketing Card module and related modules from uninstalling or reinstalling cleanly. The change avoids unnecessary cleanup work during uninstallation, reducing database leftovers and reinstall errors.
Original PR description
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for…
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for uninstallation, all its fields get removed first (because that's how `_module_data_uninstall` does things), so all the non-magic columns are dropped. Then, when trying to `unlink` the `ir.model` records the `unlink` call fails with some sort of "column does not exist" error (on `active` or `res_model`), the unlink fails, which leads the tables to not be removed, leaving a ton of garbage in the database. This in turns means trying to reinstall the module also fails, as many tables will have a few records left for one reason or another before they are dropped, so new columns which are `required` without a `default` fail to set up their constraint, which logs both errors and warnings on reinstall. None of this is necessary, if `marketing_card` is being uninstalled we can just ignore the entire issue as the table should be dropped eventually, even if it worked it would be a waste of time. https://runbot.odoo.com/odoo/error/230837 Forward-Port-Of: odoo/odoo#222789
Unbuilding a manufacturing order now restores component stock with the correct owner information. This prevents consigned materials from being mixed into regular company-owned stock, keeping inventory ownership accurate.
Original PR description
**Problem:** when a MO is unbuild, if some components where consigned, they will come back in stock as not consigned **Steps to reproduce:** - enable "consignemnet" setting - create a storable…
**Problem:** when a MO is unbuild, if some components where consigned, they will come back in stock as not consigned **Steps to reproduce:** - enable "consignemnet" setting - create a storable product (the comp) - set on on hand quantity of 3 without owner - set on on hand quantity of 4 with an owner - create another product (the final product), with a BOM of 7 of the comp product - create a manufacturing order for the final product, confirm and produce all. - unbuild it - open the comp product form, click on the on hand smart button **Current behavior:** - there is a quantity of 7 unconsigned **Expected behavior:** - there should be a quantity of 3 unconsigned and a quantity of 4 consigned **Cause of the issue:** when the stock move line is create in action_unbuild() there is no mechanism to get back the owner of the original stock move line from the MO https://github.com/odoo/odoo/blob/ceccb92af19a6a3fc0c7b5924d9f497b1aec1d55/addons/mrp/models/mrp_unbuild.py#L204 opw-4900386 Forward-Port-Of: odoo/odoo#222491 Forward-Port-Of: odoo/odoo#219905
When a user deletes a reply in Odoo Discuss or Mail, the removed message no longer keeps showing the original parent message reference. This keeps conversations cleaner and avoids confusing users with leftover reply context for content that has been deleted.
Original PR description
**Current behavior before PR:** When a user replies to a message and then deletes it, the message body changes to 'This message has been removed.' However, the mention of the parent message remains visible. **Desired behavior after PR is merged:** The parent message mention is no longer shown if the message is deleted. Task-4593293 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222488 Forward-Port-Of: odoo/odoo#198768
This fixes an issue in the HTML editor where replacing text with the same content could be ignored incorrectly when the text was part of newly added content. The change helps ensure editor history and undo behavior remain reliable after recent website builder updates.
This fix prevents upgrade errors when one app changes a shared field to be company-specific while another app is being updated. It helps keep database upgrades reliable and reduces the risk of interruptions during module updates.
Original PR description
before this commit: if module_A has a field ``company_dependent=False`` and module_B override it to ``company_dependent=True`` When -u module_A, there would be an error since ORM tries to convert column type of the field from varchar/integer/boolean... to jsonb This commit will add a patch to the field in the ORM registry if the field was company dependent before upgrade. 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 Forward-Port-Of: odoo/odoo#222701 Forward-Port-Of: odoo/odoo#220983
This fixes an issue in the website editor where removing a parallax scroll effect from a cover section could also remove its color filter. Users can now adjust scroll effects without accidentally changing the visual styling of their page.
Original PR description
After this [commit], we'd have an issue when we tried to remove the parallax (set the scroll effect to none) and had a color filter. To reproduce the problem: - Open Website and start editing; - Drop a `cover` snippet and click on it; - Set the scroll effect to None => The color filter is removed. This commit follows the [html_builder refactoring]. [commit]: https://github.com/odoo/odoo/commit/eea7216e5e366c2 [html_builder refactoring]: https://github.com/odoo/odoo/commit/9fe45e2b7ddb
Website form rules now keep the correct checkbox names when options are renamed or added. This prevents conditional visibility settings from showing outdated or missing options, making form setup more reliable for website editors.
Original PR description
[FIX] html_builder, *: use name for multiple checkbox form field *: website Steps to reproduce the problem: - Add a form snippet on the website. - Add a "Multiple Checkboxes" field in the form and…
[FIX] html_builder, *: use name for multiple checkbox form field
*: website
Steps to reproduce the problem:
- Add a form snippet on the website.
- Add a "Multiple Checkboxes" field in the form and change the name of a
checkbox.
- Make the first field depend on the "Multiple Checkboxes".
-> The name of the checkboxes are not correct.
When the user changes the name of a checkbox, there is a re-redendering
of the entire field. The problem here is double:
- The template used for the re-redendering is based on the `id`
attribute given as parameter to correctly set the `value` attribute of
the `input` of the checkbox. Since the [website refactoring], the
parameter was not not correctly computed as an unexplainable
`isFieldElCustom` condition was introduced. Due to it, the `value`
attributes of all the `input` checkboxes were wrongly set.
- The system was not updating the `id` attribute with the new user
value. Due to it, the system failed at setting the correct `value`
attribute of the renamed field.
----------------------------------------------------------------------------------------------------------------------------------------------------------
[FIX] html_builder, *: update value list on multiple checkbox add option
*: website
Steps to reproduce the problem:
- Add a form snippet on the website.
- Add a "Multiple Checkboxes" field in the form and make the first field
depend on this one ("Visible only if", "Custom Text", "Is equal to",
"Option 1").
- Click on "Add new Checkbox".
- Click on the first field and open the dropdown to try to change
"Option 1" to "Item" (the new checkbox).
-> The new checkbox is not in the list.
When the user adds a new checkbox, there is a re-redendering of the
entire field. The problem is that the template used for the
re-redendering is based on the `id` attribute given as parameter to
correctly set the `value` attribute of the `input` of the checkbox. This
commit re-introduces this parameter as it was missing when adding a new
checkbox since the [website refactoring].
----------------------------------------------------------------------------------------------------------------------------------------------------------
[FIX] website: refresh visibility option names
Steps to reproduce the problem:
- Add a form field on the website
- Add a "Multiple Checkboxes" field in the form and make the first field
depend on this one ("Visible only if", "Custom Text", "Is equal to",
"Option 1").
- Select "Option 1" and change its name.
- Click on the first field.
-> The UI shows "Visible only if", "Custom Text", "Is equal to", "None".
The problem is that since the [website refactoring], the update of
dependencies done when a field was replaced was missing.
Related to task-4367641
[website refactoring]: https://github.com/odoo/odoo/commit/9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2This fixes an issue where portal pages could receive incorrect access information for document discussions, making the system think a user had read access when they did not. The change ensures access details reflect the user's real permissions, helping avoid misleading interface behavior around chatter and shared links.
Original PR description
Before this commit, the `_thread_to_store` method would always set the `hasReadAccess` property to true. This was fine because the only flow that would add the values to the store would already check the existance and access to the thread. However after change [1] the access values would be sent in more flows, one of which being portal chatter initialization. This causes the client to have incorrect access information to the thread (i.e. hasReadAccess would be true even when accessing portal document through token). This commit fixes the issue by sending the correct access values. [1] https://github.com/odoo/odoo/pull/220774 Forward-Port-Of: odoo/odoo#222545 Forward-Port-Of: odoo/odoo#222281
Preparation receipts in Point of Sale now show key order details in a larger, easier-to-read format. They also include scheduled preparation time when timing is used, helping staff prepare orders at the right moment.
Original PR description
- Increase the size of the `order_reference`, `tracking_number`, order lines and title element on the order changes preparation receipts. - Also ensure that the preparation receipt contains the `preset_time` information when a preset with `use_timing` is used for the order. task-id: 4936935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218981
This fix prevents an error when a user presses Enter in chat group search before slow-loading results are ready. Users can continue using messaging search without seeing a disruptive JavaScript crash during brief network delays.
Original PR description
Description of the issue/feature this PR addresses: --- **Reason for PR** When a user searches for a chat group, if the network is slow and the search results have not yet been loaded, pressing **Enter** will cause the system to attempt to access the `unselectable` property of an `option` variable that is not yet initialized. This leads to the following error: ``` Uncaught Javascript Error: undefined is not an object (evaluating 'option.unselectable') ``` This PR adds handling to prevent the error when data has not been fully loaded. --- Current behavior before PR: https://github.com/user-attachments/assets/de3964c7-ff83-4f94-bc1a-cb8e09bfb62f --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222576
Fixed an issue where computing geolocation for a contact without a name could fail with an error. Users can now run address-based geolocation on incomplete contact records without interruption, and messages identify affected contacts more clearly.
Original PR description
<b>Steps to reproduce:</b> 1. Install base_geolocalize and Contacts > Go to Contacts. 2. Create a new contact or select an existing one (Individual). 3. Go to Contacts & Addresses > Add, leave all…
<b>Steps to reproduce:</b>
1. Install base_geolocalize and Contacts > Go to Contacts.
2. Create a new contact or select an existing one (Individual).
3. Go to Contacts & Addresses > Add, leave all fields empty, then Save & Close.
4. Open the newly created sub-contact > Partner Assignment > Geolocation
5. Click "Compute based on address".
<b>Issue:</b>
- Traceback is raised during geolocation computation if the sub-contact has no name Instead of Displaying.
<b>Cause:</b>
- If a partner does not have a name, the value is False.
- The join() operation results in a TypeError because False cannot be concatenated with strings.
<b>Problematic line:</b>
`'message': _('No match found for %(partner_names)s address(es).', partner_names=', '.join(partners_not_geo_localized.mapped('name')))`
<b>Solution:</b>
- Replaced `name` with `display_name` to ensure all elements passed to`join()` are strings.
This also improves readability in the UI when identifying partners without proper names.
opw-4930258
Forward-Port-Of: odoo/odoo#222317
Forward-Port-Of: odoo/odoo#218292Purchase orders now choose the correct vendor price list entry based on the applicable minimum quantity instead of automatically selecting the cheapest line. This prevents products from being added with bulk-pricing terms when the ordered quantity does not qualify, improving purchasing accuracy.
Original PR description
Steps to reproduce the bug: - Create a storable product “P1” - Under the Purchase tab: - add two vendor pricelist entries: 1:/ - Vendor: Azure Interior - min_qty: 1 - Price: $5 2:/ - Vendor: Azure…
Steps to reproduce the bug:
- Create a storable product “P1”
- Under the Purchase tab:
- add two vendor pricelist entries:
1:/
- Vendor: Azure Interior
- min_qty: 1
- Price: $5
2:/
- Vendor: Azure Interior
- min_qty: 100
- Price: $2
- Create a purchase order:
- vendor: Azure Interior
- Try to add the product P1
**Problem:**
When adding a product to a purchase order, if multiple supplier info
lines exist for the same vendor, the one with the lowest price will be
selected, instead of the one matching the smallest applicable quantity
(min_qty).
This regression was introduced by the following commit, which
tried to fix an unrelated bug with supplier info date matching:
https://github.com/odoo/odoo/commit/7eabfcff402993f32f5c835e18e07c91782a7b33#diff-5684edced9bdfc98021a85de4c6cdf691ea7add74e56ab50334a1d7db9ef4224L470
As part of that fix, the logic was changed to use the _select_seller
method, which by default sorts supplier info lines by price_discounted
and returns the first one — regardless of whether the min_qty is met.
Previously, the logic correctly selected the supplier line based
on min_qty when multiple lines existed for the same vendor.
**_Note:_** This bug is no longer present as of version 18.1, because
the date-related issue was fixed differently in the following commit:
https://github.com/odoo/odoo/commit/19c65c4884a3746b44b6272694662eb32a6bf32f
That later fix preserved the original behavior of respecting min_qty.
**Solution:**
Explicitly pass ordered_by='min_qty' when calling _select_seller.
This ensures that supplier info lines are prioritized based on the
lowest applicable min_qty, not the lowest price, when the vendor is the
same.
opw-4942819
Forward-Port-Of: odoo/odoo#221902
Forward-Port-Of: odoo/odoo#221764This change prevents an access error when a user from one company views products on an eCommerce website owned by another company. It ensures the website can retrieve the correct company currency when no pricelist is configured, improving multi-company shopping reliability.
Original PR description
A multi-company issue can occur when a user from another company tries to access products belonging to a different company. Steps to reproduce: 1. Create a e-commerce website without a pricelist on company A 2. Create a user assigned with only access to company B 3. Connect with this user and try to access the products on the website of company A An error will be raised because the user does not have access to company A. opw-4983506 Forward-Port-Of: odoo/odoo#222656 Forward-Port-Of: odoo/odoo#222457
PDF reports for multiple records now fall back to generating each document separately when automatic splitting cannot be completed reliably. This prevents missing or incorrect report files in cases where report structure or PDF tooling produces inconsistent page outlines, though very large batches may take longer to process.
Original PR description
When generating PDF reports with multiple records, the system tries to split the concatenated PDF using outlines. However, in cases where the number of outlines doesn't match the number of records or…
When generating PDF reports with multiple records, the system tries to split the concatenated PDF using outlines. However, in cases where the number of outlines doesn't match the number of records or outlines are missing, it falls back to generating individual PDFs per record by recursively calling `_render_qweb_pdf_prepare_streams()` for each `res_id`.
This ensures that each record gets its corresponding PDF even if splitting the combined PDF is not possible due to template or wkhtmltopdf inconsistencies.
issue related: https://github.com/odoo/odoo/issues/202299
Current Behavior:
The _render_qweb_pdf_prepare_streams method does not correctly generate PDF streams under specific conditions, causing the PDF to not be properly split for each res_id. When these conditions are met, the generated streams are set to None, resulting in incorrect PDF processing.
The issue occurs when all the following conditions are true:
reader.numPages != len(res_ids_wo_stream)
len(res_ids_wo_stream) > 1 and set(res_ids_wo_stream) == set(html_ids_wo_none) is True
not has_valid_outlines is False
has_same_number_of_outlines and has_top_level_heading is False, since has_same_number_of_outlines is False
Expected Behavior:
The method should correctly assign a valid PDF stream to each res_id, ensuring proper document splitting even when outlines cannot be used.
Steps to Reproduce:
Generate a PDF report where the number of pages does not match the number of res_ids.
Ensure that the report includes multiple records, and the outlines structure is not valid for splitting.
Debug and Observe that the streams assigned to res_ids are None, leading to issues in PDF rendering.
Error:
Odoo Server Error
RPC_ERROR
Odoo Server Error
Occured on 172.20.18.5:8069 on model ir.cron and id 31 on 2025-03-18 12:02:43 GMT
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 397, in safe_eval
return unsafe_eval(c, globals_dict, locals_dict)
File "ir.actions.server(309,)", line 1, in
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 5481, in _cron_account_move_send
self.env['account.move.send']._generate_and_send_invoices(
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 687, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 612, in _generate_invoice_documents
self._prepare_invoice_pdf_report(batch)
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 333, in _prepare_invoice_pdf_report
content_by_id = self.env['ir.actions.report']._get_splitted_report(pdf_report.report_name, content, report_type)
File "/home/odoo/src/odoo/addons/account/models/ir_actions_report.py", line 60, in _get_splitted_report
pdf_dict = {res_id: stream['stream'].getvalue() for res_id, stream in content.items()}
File "/home/odoo/src/odoo/addons/account/models/ir_actions_report.py", line 60, in
pdf_dict = {res_id: stream['stream'].getvalue() for res_id, stream in content.items()}
AttributeError: 'NoneType' object has no attribute 'getvalue'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/http.py", line 1962, in _transactioning
return service_model.retrying(func, env=self.env)
File "/home/odoo/src/odoo/odoo/service/model.py", line 156, in retrying
result = func()
File "/home/odoo/src/odoo/odoo/http.py", line 1929, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/odoo/src/odoo/odoo/http.py", line 2177, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
File "/home/odoo/src/odoo/odoo/http.py", line 727, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/odoo/src/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
File "/home/odoo/src/odoo/odoo/api.py", line 533, in call_kw
result = getattr(recs, name)(*args, **kwargs)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_cron.py", line 120, in method_direct_trigger
self.ir_actions_server_id.run()
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_actions.py", line 995, in run
res = runner(run_self, eval_context=eval_context)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_actions.py", line 827, in _run_action_code_multi
safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self)) # nocopy allows to return 'action'
File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 411, in safe_eval
raise ValueError('%r while evaluating\n%r' % (e, expr))
ValueError: AttributeError("'NoneType' object has no attribute 'getvalue'") while evaluating
'model._cron_account_move_send(job_count=20)'
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://172.20.18.5:8069/web/assets/0604b65/web.assets_web.min.js:3140:163)
at XMLHttpRequest. (http://172.20.18.5:8069/web/assets/0604b65/web.assets_web.min.js:3145:13)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#213900Fixes an issue where point of sale orders from a closed session could fail to be invoiced when cash rounding and mixed payments were used. This helps ensure invoices can be created reliably after session closure without accounting balance errors.
Original PR description
Currently it's not always possible to invoice an order from another sessio nthat is already closed when there is cash rounding. Steps to reproduce: ------------------- * Enable cash rounding for cash methods only, 5cents half-up * Open pos session * Add a produc with price 174.99 to order * Add a customer * Go to pay * Select pm cash and enter 100 * Select pm bank and enter 75 * Change 0.01 * Validate * Close session * Open session * Try invoicing the precedent order > Observation: Not possible to invoice, move is not balanced Back porting as it is exaclty the same issue: https://github.com/odoo/odoo/commit/626c3fd1bff85cc6cb222bdba80c14dd761dafd3 opw-[4829919](https://www.odoo.com/web#id=4829919&view_type=form&model=project.task) Forward-Port-Of: odoo/odoo#222543 Forward-Port-Of: odoo/odoo#220096
This fix prevents Odoo from crashing when users open an app while multiple modules are still being installed. It makes the web interface handle partially loaded view information more safely, improving reliability during installation workflows.
Original PR description
Currently, an error occurs when the user tries to install multiple modules and, during installation user tries to access any app. This issue happens because line [1] tries to get view info by view…
Currently, an error occurs when the user tries to install multiple modules and, during installation user tries to access any app. This issue happens because line [1] tries to get view info by view name, like `hierarchy`. Normally, we get the view information from the `_get_view_info` method (see [2]), and we override this method to add another view to the returned data (as in [3]). But during installation, when the user tries to access any app, the view is already loaded into the database. So when the `fields_get` method is called, the view is found. However, since the module isn't fully loaded yet, the overridden `get_view_info` method hasn't taken effect. As a result, the additional view we expect isn’t included, and accessing that view key causes an error. This commit fixes the above error by ensuring that `_view_info` is accessed only when `type_` is present in `_view_info` at [1]. [1]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web/models/ir_ui_view.py#L14 [2]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web/models/ir_ui_view.py#L22-L31 [3]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web_hierarchy/models/ir_ui_view.py#L56-L57 sentry-5661154820 Forward-Port-Of: odoo/odoo#221847
The website editor now handles failed link preview requests gracefully, such as when an external site blocks access. This prevents error screens when users preview social media or other external links while editing website content.
Original PR description
Problem: When a fetch request fails (e.g., due to CORS restrictions), a traceback occurs in the editor. Solution: Catch errors on `await this.props.getInternalMetaData`. Steps to reproduce: - Go to Website - Change the footer to "Links" - Click on a social media link to preview > A traceback occurs opw-4979674 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Some automated website tests for carousel autoplay are being turned off temporarily because timing behavior is currently inconsistent. This avoids unreliable test failures while the underlying carousel timing issue is investigated, with no direct change to customer-facing website features.
Original PR description
The first slide of a carousel after loading the page seems to happen after more than 3s, even when the interval is set to 3s. While waiting for a fix for these tests, they are temporarily disabled. task-4367641
Saudi e-invoices now place the actual payable invoice amount in the QR code instead of the related sales order total. This helps regular invoices after down payments pass ZATCA validation without warnings, supporting smoother compliance processing.
Original PR description
#### Step to reproduce: - In a company in Saudi Arabia - Create a sale order to a customer (B2C) - Create an invoice as a downpayment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) - Create an invoice as a regular payment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) #### Current behavior: - ZATCA return a 200 code for the downpayment invoice. - ZATCA return a 202 code with a Warning for the regular payment invoice. The warning states that the invoice was accepted however it needs the Tag 4 of the QR code to be Amount due payment (BT-115) #### Expected behavior - ZATCA return a 200 code on both invoices. opw-4848578 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219464
This fix corrects how repeated text changes are tracked in the HTML editor, preventing editing history from behaving incorrectly after the website builder refactor. It helps users reliably undo or redo text edits when building or updating website content.
Original PR description
This commit is a back port of 65fbdbee17acfa2cfe2129a8bda2e969018a0544 The issue it fixes was introduced during the [website builder refactor], so it was present in 18.4 [website builder refactor]: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-4367641
This fix prevents the live chat bubble from overlapping the floating shopping bar on mobile product pages. Shoppers now see and can use the floating bar consistently, whether or not a pricelist is active.
Original PR description
In odoo/odoo@860dccec53cb0940212fe7d9161c7e3c805867f7 the floating toolbar layout was introduced, but there was an issue with the livechat bubble which was overlapping the floating bar on mobile when there was no priceslit (error with the calc()). This PR fixes this issue by displaying the floatingbar above the livechat bubble, taking the same style when there is a pricelist or not. task-4966406 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221568
This fix prevents invited attendees from accidentally becoming the organizer of existing Odoo events when they start or resume Google Calendar synchronization. Events are now synchronized by the actual organizer, keeping ownership consistent between Odoo and Google Calendar.
Original PR description
Before this commit, when an user A is invited by an event of user B and none of these users are synchronized with Google, when the synchronization of user A starts or resumes, the event will be…
Before this commit, when an user A is invited by an event of user B and none of these users are synchronized with Google, when the synchronization of user A starts or resumes, the event will be synchronized with the user A as organizer in Google. In the meanwhile, in Odoo, the event ownership will be shown as user B, mismatching the organizer field between the two ends. This is problematic because the ownership of the event will be forever wrong in Google. After this commit, when user A starts or resumes its synchronization with Outlook, previous Odoo events which user A is attendee but not organizer won't be synchronized until the organizer synchronizes its calendar. This will keep the ownership of the event intact in Odoo, and when the organizer synchronizes its calendar with Google, it will be correctly synchronized in Google as well. Recently, we had to revert this PR due to an emergency at odoo/odoo#215449. The issue got solved, so we're adding this fix back. task-4269432 Forward-Port-Of: odoo/odoo#219178 Forward-Port-Of: odoo/odoo#218856
Reconciliation rules that only define an amount match can now be suggested for bank statement lines. This helps finance teams automate more bank reconciliation cases instead of handling them manually.
Original PR description
Before this commit, having a reco model with a match amount alone was never applied to statement line since the can_be_proposed field was False. This commit will add the match_amount to the compute notask-id --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221733
This fixes an issue where an emptied, protected link such as a website header button could become impossible to type into. Users can now delete and re-enter button or link text without getting stuck after editing or reopening the page.
Original PR description
In case a link is unremovable, the `zwnbsp`s (aka feffs) added on the edges of a link may be missing one inside if the link is empty. With only one feff inside the link, the user cannot move the cursor inside it Steps to reproduce: - Delete the content of an unremovable link (for example the "Contact Us" button in header of website) - Use the arrows with shift key to extend selection (`shift+right`) - Press delete - Bug: user cannot write anything inside the button Alternative: - Delete the content of an unremovable link - Save and reopen - Bug: user cannot write anything inside the button task-4954763
Calendar reminders now only appear for upcoming events within the correct reminder window. This prevents users from receiving confusing notifications for recurring meetings that already happened.
Original PR description
Steps to reproduce the issue: 1. Create a calendar event (meeting, for example) 2. Set the start date as yesterday and in 30 minutes from now. 3. Set it to be recurrent every week with end_type set…
Steps to reproduce the issue: 1. Create a calendar event (meeting, for example) 2. Set the start date as yesterday and in 30 minutes from now. 3. Set it to be recurrent every week with end_type set to end_date and in the future(1 month from now). 4. Add a reminder to the event (30 mins, for example) and ensure that calendar_last_notif_ack is set before the alarm window for your user's res.partner. 5. Save the event and observe an alarm notification made for an event in the past. After the fix, the calendar alarms will only trigger for events in the future and in their designated time windows. The recurrence logic was also removed from the query to align with this [[REF]](https://github.com/odoo/odoo/pull/42031/commits/a27afdb5434166c3ea48c18ccfba9e8245d18e62) since recurring events are all persistent records in the database. opw-4776638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222610 Forward-Port-Of: odoo/odoo#222214
Physical Inventory no longer shows a duplicate serial number warning when a serialized product has simply been moved between locations. This avoids confusing alerts caused by old zero-quantity stock records, improving confidence in inventory checks.
Original PR description
## Issue: ## A warning appears in Physical Inventory when transferring a product with a serial number between two locations ## Cause: ## The `_compute_sn_duplicated()` method incorrectly considered…
## Issue: ## A warning appears in Physical Inventory when transferring a product with a serial number between two locations ## Cause: ## The `_compute_sn_duplicated()` method incorrectly considered `stock.quant` records with quantity 0 That mean that it will considered a duplication even if the quant indicate that the product isn't in that location Additionally, the system parameter `stock.skip_quant_tasks` is enabled on all SaaS environments since version 18.2 It was added for performance issues: (see: https://github.com/odoo/odoo/commit/207ba01819577cf6a2a686fae39dd3d673aec6dd) When enabled, the quant merging and removal of zero quants are skipped when opening a Physical Inventory, causing this issue to appear ## Steps to reproduce: ## - Enable Developer Mode - Create a New System Parameter (Key: stock.skip_quant_tasks, Value: True) - In Settings, enable Storage Locations and Lots & Serial Numbers - Duplicate WH/Stock as WH/Stock (copy) - Create a product tracked by Unique Serial Number - Update its quantity: one at WH/Stock - Process an Internal Transfert from WH/Stock to WH/Stock (copy) - Go in Operations > Adjustments > Physical Inventory opw-4944011 Forward-Port-Of: odoo/odoo#221578
This fixes an issue that could prevent Spain's Modelo 111 tax report from opening after a reporting engine change. The update removes incompatible grouping settings so users can access the report without encountering an error.
Original PR description
Commit https://github.com/odoo/odoo/commit/97fe24cea74241a7820841a470994d3ebf9d8d38 changed the engine for some report line of Modelo 111. The new engine used, `external`, is not compatible with…
Commit https://github.com/odoo/odoo/commit/97fe24cea74241a7820841a470994d3ebf9d8d38 changed the engine for some report line of Modelo 111. The new engine used, `external`, is not compatible with having a grouping value defined by the user (field `user_groupby`). Except that value does not get removed from the report lines. As a result, a traceback pops up whenever we try to access the report. Two previous commits aimed to sync that field with the `groupby` field (https://github.com/odoo/odoo/commit/a7d54c76aaee325449248fa698adb9e549c486ee), and update it if it was not compatible with the engine (https://github.com/odoo/odoo/commit/0d5bf820c3737ee3e4af54d1fb556b72d6c59c3d) but both only work with `aggregation` engine. This commit makes `_validate_engine()` account for `external` engine, as it was only checking for `aggregation` engine when validating `groupby` related fields. opw-4972212 opw-4971497 opw-4931269 opw-4949654 Forward-Port-Of: odoo/odoo#221407 Forward-Port-Of: odoo/odoo#221021
The website builder now clears its edit history after a save completes, including saves triggered during actions like switching themes or adding languages. This prevents users from seeing an unnecessary warning that changes will be lost when their work has already been saved.
Original PR description
Some actions (like "Switch Theme" or "Add Language") perform a save during their `apply` followed by a change of page. The change of page is blocked by a dialog (with a warning about lost changes) because there is a step added after the end of the call to their `apply`. The commit 30bbe413f1122bf243eb6e073be6fa19dddf984a already fixed similar issues, but did not handled that case (`save` that adds mutations and is called inside `apply`). By resetting the history at the end of a save, the extra step is not added (unless something actually made more changes after the save). Steps to reproduce: - Open website builder - Drop a snippet (or do an other change) - In the "Theme" tab, click "Switch Theme" - A "Confirmation" dialog appears, telling it will save the changes - Click "Ok" - Bug: There is a dialog that appears, telling the changes will be lost (The changes won't be lost) task-4367641
Purchase orders created from sales orders now keep the linked project in make-to-order, buy, and drop-shipping flows. This helps teams keep purchasing costs and follow-up work correctly tied to the right customer project without needing extra modules installed.
Original PR description
This commit fixes two issues related to project propagation from Sale Order to Purchase Order: **1. Project not propagated when using MTO+Buy route** **Steps to reproduce:** - Install only…
This commit fixes two issues related to project propagation from Sale Order to Purchase Order: **1. Project not propagated when using MTO+Buy route** **Steps to reproduce:** - Install only `sale_project_stock` and `purchase` - Enable multi-step routes and unarchive the "MTO" route - Create a storable product "P1" with: - Routes: MTO + Buy - Vendor: any - Create a Sale Order with: - 1 unit of P1 - Any project set in "Other Info" - Confirm the SO **Issue:** A Purchase Order is created but the project is not propagated to it. This propagation was previously ensured by `project_mrp_sale`, via: https://github.com/odoo/odoo/blob/238a41e35280256382f6509182b9e900fb4f7aba/addons/project_mrp_sale/models/stock_move.py#L9 --- **2. Project not propagated when using drop-shipping** **Steps to reproduce:** - Enable drop-shipping - Create a product "P2" with: - Route: Drop-Ship - Create a Sale Order with: - 1 unit of P2 - Any project set - Confirm the SO **Issue:** A Purchase Order is created, but the project is again missing. --- **Fix:** - Move the `_prepare_procurement_values` override from `project_mrp_sale` to `sale_project_stock` to ensure project propagation regardless of the presence of `project_mrp_sale` - Also adapt `sale_project` to ensure project is retrieved from the Sale Order if not set on the Sale Order Line. opw-4976606 Forward-Port-Of: odoo/odoo#222390 Forward-Port-Of: odoo/odoo#222179
This fixes an incorrect label for the user group related to creating products. The change helps administrators see the right permission name, reducing confusion when managing product access settings.
Incoming return slips now show the proper destination address instead of placeholder demo text. This prevents confusion for warehouse teams and customers when printing return documentation for received products.
Original PR description
Issue ----- Incoming return slips have a "Demo Address and Name" text instead of the correct destination address. <img width="928" height="658" alt="image"…
Issue ----- Incoming return slips have a "Demo Address and Name" text instead of the correct destination address. <img width="928" height="658" alt="image" src="https://github.com/user-attachments/assets/6ff0a5e7-f1ee-4faa-a22b-76ec8f2f7a28" /> Steps to reproduce ----- - Create a receipt for a product - Print its return slip Cause ----- By default, the address is taken from the pickings location_id -> warehouse_id -> partner_id. For incoming pickings, the warehouse is the vendor one, with no associated partner. In such cases, the partner can be found directly on the picking itself with the partner_id field. Note ----- To render t-fields, qweb first applies a `rsplit` before evaluating the expression, see https://github.com/odoo/odoo/blob/cb1c761777e84d96f82c4f754586795509ce1b3d/odoo/addons/base/models/ir_qweb.py#L2015-L2016 With this in mind, using parentheses and moving `.partner_id` outside of them seems like the most readable way to go about it. ----- Ticket: opw-4660716 Forward-Port-Of: odoo/odoo#221807 Forward-Port-Of: odoo/odoo#219011
Steps to reproduce: 1. Install 'l10n_it' and 'accounting' from apps. 2. Enable debug mode. 3. Activate the Italian language and set it for the current user. 4. Go to Accounting > Customers / Vendors > Invoice / Bill > Electronic Invoicing tab Observation: When the Italian language is active, the 'Electronic Invoicing' tab and the fields within it are not translated. Issue: Missing translations in the PO file. Solution: Added the missing translations for the fields in the PO file.
Original PR description
Steps to reproduce: 1. Install 'l10n_it' and 'accounting' from apps. 2. Enable debug mode. 3. Activate the Italian language and set it for the current user. 4. Go to Accounting > Customers / Vendors > Invoice / Bill > Electronic Invoicing tab Observation: When the Italian language is active, the 'Electronic Invoicing' tab and the fields within it are not translated. Issue: Missing translations in the PO file. Solution: Added the missing translations for the fields in the PO file. opw-4937464 Forward-Port-Of: odoo/odoo#222322
This fix ensures subscription effective dates are properly saved when orders are processed. It prevents cases where a date appeared to be set but was not written to the database, improving reliability for subscription records.
Original PR description
Since https://github.com/odoo/enterprise/commit/ff8e55ed83d4905584b7ea10b60ded0d7afbd0cf setting the effective date is done in a precommit hook. Problem, the precommit don't automatically flush. The value set in the cache may be never reflected in the database. Solution: Explicitly flush in the precommit hook Forward-Port-Of: odoo/enterprise#92283
This fixes an issue in the Documents app where a sharing email template referred to information that is not available on document access records. The correction helps prevent errors when the template is created during upgrades, improving reliability for document sharing setup.
Original PR description
As `documents.access` records do not have `create_uid`, it isn't possible to reference it. This only comes up now as we've fixed the upgrade scripts to actually create this record (in odoo/upgrade#7959). Task-4480388
This update ensures point-of-sale order totals in the Mexican electronic invoicing flow are rounded using the currency's official precision. It prevents valid fully discounted orders from being incorrectly blocked by a validation error caused by tiny rounding differences.
Original PR description
Issue: With specific prices and discounts, we can get an rounding issue that does not pass the Validation Error. Purpose of this PR: To round the amount total based on the currency's rounding precision to pass the check. Steps to Reproduce on Runbot: install pos, l10n_mx create products prices with 75.00 and 60.00 respectively. create discount 100% on order change decimal accuracy to 3, change tax to Include with Price create PoS order with products and apply discount receive ValidationError even though the amount total should be rounded to 0.0. opw-4944830 Forward-Port-Of: odoo/enterprise#92141
This fix ensures stock quantity update notification tests include an email address so notifications can be sent correctly. It helps prevent failures around stock move updates when required contact details are missing.
Original PR description
Updating the initial demand of a stock move notify the users. Without email address, the notification cannot be send. As the email address of the admin user is only fill in the demo data, this commit adds one specially for the test. runbot: 226778 Forward-Port-Of: odoo/enterprise#91103 Forward-Port-Of: odoo/enterprise#89722
The Documents app button is now shown to all internal users, making it easier for them to access shared documents. This also clarifies that users do not need the full Documents User role to open documents shared with all internal users.
Original PR description
The app is accessible to all internal users via smart buttons and their portal already, showing the button is helpful in two ways: 1/ Easier access to the app, duh. 2/ Makes it explicit that you don't need to be a "Documents User" to have access to documents shared with all **internal users**, even those that are not documents user (that didn't have the app button available). In 18.0 so that new installations have it. Task-4889053 Forward-Port-Of: odoo/enterprise#92124 Forward-Port-Of: odoo/enterprise#90937
The Argentina electronic invoicing test setup will now stop retrying after a small number of failed connection attempts instead of looping indefinitely. This reduces wasted testing time and avoids repeatedly hitting external services when they are unavailable.
Original PR description
In 18.0 and above test hasn't worked in months, half the time it fails because pretty much nothing works in it and half the time it's because it keeps looping on trying to set up the connection and failing (possibly because we're getting blacklisted due to how much spamming we do). For now restrict to just trying 5 times (per class since it's called from a `setUpClass`) with an exponential backoff. This may yet end up in removing the entire test directory as it doesn't seem like anyone cares. Forward-Port-Of: odoo/enterprise#92226 Forward-Port-Of: odoo/enterprise#92207
This fix updates demo employee records so they use the correct payroll structure type in several country-specific payroll modules. It helps ensure sample payroll data behaves as expected during demonstrations, testing, and evaluations.
Original PR description
Some employees on demo data don't have the correct structure type. This solves this issue. Task: 4890507
The portal now shows total hours based only on validated timesheets when the validated-timesheets-only invoicing policy is enabled. This prevents customers from seeing inflated hours that include unvalidated work, keeping portal totals aligned with the visible timesheet lines.
Original PR description
### Steps to reproduce: - Set timesheets inovicing policy to 'Validated Timesheets Only' - From the portal go to any task that has some validated timesheet and some other not - Notice that the lines…
### Steps to reproduce: - Set timesheets inovicing policy to 'Validated Timesheets Only' - From the portal go to any task that has some validated timesheet and some other not - Notice that the lines shown is the validated ones only but the Hours spent includes the non-validated ones too ### Current behavior before PR: The total hours spent for timesheets in portal view when setting the invoicing policy to 'Validate Timesheets Only' is calculated wrongly as it takes the non validated ones into account. This is happening as when passing the values to the view we pass 'task_sudo' variable which will have the SUPERUSER as the env.user https://github.com/odoo/odoo/blob/saas-17.2/addons/project/controllers/portal.py#L569 so it won't pass the condition if the user is portal or not https://github.com/odoo/enterprise/blob/saas-17.2/sale_timesheet_enterprise/models/project_task.py#L33:L35 and it will calculate all the timesheet without taking validation into condisderation. ### Desired behavior after PR is merged: As we are using those computed fields only in portal views so we don't have to check if the user is portal user as even if an internal user is showing the same view for testing he should be able to see the same data as the portal user. opw-4193842 Forward-Port-Of: odoo/enterprise#70557
Belgian Group S payroll exports now correctly support selecting another active company instead of being limited to the user's current company. The export also checks that the selected company has its required Group S code set, helping prevent incomplete or rejected work entry exports.
Original PR description
before this commit only the current company was taken into account when exporting work entries now another company can be selected if multiple companies are active for the current user In addition to that this commit also add a check for the company's group s code to enforce the user to set it before exporting work entries task-4213675 closes old PR: odoo/enterprise/pull/71521 Forward-Port-Of: odoo/enterprise#89438
Rental orders now create the right number of planning shifts based on the selected unit of measure, and those shifts are automatically published. The update also prevents staff from adding shifts to rental order lines that are already fully planned, reducing overbooking mistakes.
Original PR description
## [FIX] sale_renting_planning: make sure shift generated by RO is published ## [FIX] sale_renting_planning: generate shifts when confirming rental order based on uom Before this commit, when the…
## [FIX] sale_renting_planning: make sure shift generated by RO is published ## [FIX] sale_renting_planning: generate shifts when confirming rental order based on uom Before this commit, when the user creates room product to generate shifts when a rental order is confirmed with that product, we expect to generate one shift per quantity ordered if the UoM is Unit instead of Hours/Days. This commit improves the shifts generation to take into account the UoM set on the SOL linked to rental order confirmed. That is, if the UoM set is Unit then one slot per unit ordered of the product will be generated. Otherwise, one shift will be generated for the SOL as it is currently the case. ## [FIX] sale_renting_planning: make sure to not overload the rental service Before this commit, when the user creates a new shift and clicks on `Add to Last Order` the shift will be added to the SOL contained one of products linked to the role set on the shift. The problem is we don't check if there is still something to plan for that SOL. This commit makes sure the SOL to set to the shift has something to plan to be sure it is not overloaded. task-4916537
Online synchronization fields will remain visible even when provider details are no longer supplied by Odoofin. This prevents users from losing access to important setup or management fields and includes a correction to related search behavior.
Original PR description
The fields on the online synchronization were invisible if no provider_data was put on the synchro. But now, this info is not given anymore from Odoofin. So, we should not hide these fields based on provider_data. Also fixed a search domain. It will need an update of the module. This is a manual fw-port of https://github.com/odoo/enterprise/commit/a98b4bb4d982072043a7ed6f8b4917be1d1ab974
Expiration dates shown in the Barcode app are now displayed using the user's local timezone, preventing dates entered at midnight from appearing as the previous day. This helps warehouse teams avoid confusion when receiving lot-tracked products with expiry dates.
Original PR description
**Issue**: The expiration date displayed in the barcode app's scan screen may appear incorrect. **Steps to reproduce**: - Go to Settings > Inventory, and enable the `Expiration Date` field - Open the…
**Issue**: The expiration date displayed in the barcode app's scan screen may appear incorrect. **Steps to reproduce**: - Go to Settings > Inventory, and enable the `Expiration Date` field - Open the Purchase app - Create a new Request For Quotation - Select a product that: - is a good tracked by lot - has the `Expiration Date` field enabled (Inventory tab > Traceability) - Confirm the RFQ - Click the `Receipt` smart button - Click the `hamburger button` and enter an expiration date at midnight. - Go to the Barcode application > Operation > Receipts - Open the corresponding RFQ - Click Edit and increase the quantity to 1, then Validate - Observe that the date is displayed as one day earlier **Cause**: The code https://github.com/odoo/enterprise/blob/b5ad18b101f4a2608758762edf0f49270a67ba20/stock_barcode_product_expiry/static/src/components/line.js#L17 assumes that the date is encoded using the local while the date comes from the server https://github.com/odoo/enterprise/blob/b5ad18b101f4a2608758762edf0f49270a67ba20/stock_barcode_product_expiry/static/src/components/line.js#L13, and thus is utc encoded. So for example, if the user's timezone is `Europe/Brussels`, a midnight timestamp will appear as 10 PM the previous day. **Solution**: To solve this issue, use this method https://github.com/odoo/odoo/blob/7a40285fd03f75f07a74f05d4b60e760e1c83eb3/addons/web/static/src/core/l10n/dates.js#L619-L622 instead of https://github.com/odoo/odoo/blob/7a40285fd03f75f07a74f05d4b60e760e1c83eb3/addons/web/static/src/core/l10n/dates.js#L514-L516. This way, it would parse the utc-base server date as a utc-base date. opw-4865513 Forward-Port-Of: odoo/enterprise#91517 Forward-Port-Of: odoo/enterprise#88526
The accounting reports test suite now avoids applying unsupported grouping checks to reports that use external calculation logic. This keeps complex localized tax reports, such as Luxembourg annexes, from failing automated validation due to rules that do not apply to them.
Original PR description
The corresponding community PR (https://github.com/odoo/odoo/pull/221407) contains a fix that requires the _validate_engine constraint to reject any groupby value for the 'external' engine. Therefore, it is now needed that the test ensuring non-stored related fields can be used in groupby is adapted in order to also exclude those expressions when changing the groupby value of the lines using a custom engine on any of their expressions. Without that, complex reports like the annexes of the Luxembourgese tax report fail the test. Forward-Port-Of: odoo/enterprise#92096
Field service users can once again open outgoing stock pickings in a map view. This restores the expected enterprise-only map option after a related community fix, helping teams plan and visualize delivery routes more easily.
Original PR description
This commit is the continuity of the fix made in community. The issue fixed in community was the map view cannot be defined in the view mode of an action since the map view only exists in enterprise. This commit overrides the method defined in community to add the map view as before. Related PR: odoo/odoo#222003 Forward-Port-Of: odoo/enterprise#92032
36 changes
Resolved issues and error corrections
This fixes a mismatch in Portuguese vendor bills when a user manually adjusts a tax amount. Tax totals now stay aligned with the accounting entries, reducing confusion and helping invoices reflect the correct untaxed amount.
Original PR description
Create a vendor bill with a base of 123 and 23% tax. => untaxed_amount = 123 & amount_tax = 28.29 Edit the tax amount to be 28.30 => The tax totals shows an untaxed_amount of 122.99 but the accounting entries say 123.0 This is because during the rounding, since the tax computation is custom in Portugal, we subtract the tax amount from the total amount to get the expected base amount. Since the total is not updated according the tax lines, the base amount takes the difference instead of the total. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220635
This fix prevents an unrelated payment provider card selector from appearing when a POS payment method is configured for online payments. It keeps the setup form clearer and reduces the chance of choosing an incompatible payment option.
Original PR description
Before this commit, when the `is_online_payment` field was set to `True` the widget `pos_payment_provider_cards` was not properly hidden in the form view of the POS payment method. This commit ensures that the widget is correctly hidden when the field is set to `True` by resetting the `payment_method_type` to 'none'. Thanks to @elierwclik for the report and initial PR #222142 Forward-Port-Of: odoo/odoo#222356
This fix prevents confusing system errors when a document numbering format contains an invalid placeholder. Users will now receive a clear warning so they can correct the sequence setup without disrupting document creation unexpectedly.
Original PR description
Currently, an error is raised when a sequence is generated with an invalid legend in the prefix or suffix. **Steps to reproduce:** - Install Sales module. - Update the sale order sequence prefix to S%(days)s. - Create a new sale order. **Error:** `KeyError - 'days'` **Cause:** An error occurs when the user provides an invalid suffix in `ir_sequence` and the system tries to generate that sequence at [1]. [1] - https://github.com/odoo/odoo/blob/18da9b6dfc9dc376700cd948a09ae201bf897990/odoo/addons/base/models/ir_sequence.py#L235-L236 **Fix:** To resolve the issue, raise a user error for an invalid sequence. **Ref:** https://github.com/odoo/odoo/commit/18cac1caa21149d70009aa50f3e90dfbc18456a3 Sentry - 6684586181 Forward-Port-Of: odoo/odoo#222527 Forward-Port-Of: odoo/odoo#217142
This fix prevents the Marketing Card module from blocking clean uninstallation when its database fields have already been removed. It helps avoid leftover database data and reinstall errors for Marketing Card and related modules.
Original PR description
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for…
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for uninstallation, all its fields get removed first (because that's how `_module_data_uninstall` does things), so all the non-magic columns are dropped. Then, when trying to `unlink` the `ir.model` records the `unlink` call fails with some sort of "column does not exist" error (on `active` or `res_model`), the unlink fails, which leads the tables to not be removed, leaving a ton of garbage in the database. This in turns means trying to reinstall the module also fails, as many tables will have a few records left for one reason or another before they are dropped, so new columns which are `required` without a `default` fail to set up their constraint, which logs both errors and warnings on reinstall. None of this is necessary, if `marketing_card` is being uninstalled we can just ignore the entire issue as the table should be dropped eventually, even if it worked it would be a waste of time. https://runbot.odoo.com/odoo/error/230837 Forward-Port-Of: odoo/odoo#222789
Restoring an earlier task description from history now keeps the information needed for later saves. This prevents users from seeing an incorrect history-related error after applying a previous version and editing the task again.
Original PR description
Problem: When applying a specific version from history in `task.description`, then updating and saving it, an error appears stating the content was saved from a different history model. Cause: When inserting versioned content, the required `data-last-history-steps` attribute is not included. Solution: Ensure the latest `data-last-history-steps` is added when restoring a version. Steps to reproduce: - Open Project > any task - Change the description - Save - Open version history and apply any version - Update the description - Save - Error appears opw-4829553 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216370
Activity list filters now focus on the current user's own activity deadlines instead of mixing in deadlines from other users on the same record. This makes late, today, and future activity views match what users expect from the activity counter and reduces confusing search results.
Original PR description
Partially revert [1] as users expect to see the deadline of their next activity, matching the count displayed in the systray menu. Currently clicking "future activities" for example will show you all records with *any* future activity so long as the next one is yours. Even if yours is actually late. The mistake seems to be that "my activities" + "next date deadline < X" is equivalent to "my next date deadline < X". But this is not the case as just because the most late activity is not yours does not mean you do not have any late activity. As the more common use case is to view your own activities, that should be what the filter shows. Users may create their own filters to find records based on the next overall deadline. As such the filters are reverted to their previous expression. And the "my activities" filter is not selected by default. [1]: 5c5fbc10b7024c7227f03e37897d421bba64df82 task-4988330
This fixes an error that could block invoice printing when online payment QR codes were enabled. Sales-created invoices can now be printed normally with the QR payment link included, avoiding disruption in the invoicing workflow.
Original PR description
### Issue When "Add QR-code link on PDF" is enabled, printing an invoice in a regular Sales → Accounting flow raises an error. The report printing process internally calls…
### Issue
When "Add QR-code link on PDF" is enabled, printing an invoice in a regular Sales → Accounting flow raises an error.
The report printing process internally calls
`_generate_portal_payment_qr`, which creates a `payment.link.wizard` record. This model overrides `default_get` and reads `self.env.context.get('active_model')`.
At that moment, the context still contains `'sale.advance.payment.inv'`, a model that does not implement `_get_default_payment_link_values`. This causes:
AttributeError: 'sale.advance.payment.inv' object has no attribute '_get_default_payment_link_values'
#### Affected versions
- saas-18.3 and later
### Steps to reproduce
1. Install `account_accountant`, `sale_management`
2. Go to Settings
3. Enable "Invoice Online Payment" and "Add QR-code link on PDF"
4. Go to Sales → Quotations
5. Create any quotation
6. Confirm quotation
7. Create invoice (full)
8. Confirm invoice
9. Click "Print"
#### Current behavior
- Error is raised
#### Expected behavior
- Invoice prints with QR code without error
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prUnbuilding a manufacturing order now restores component stock with the correct ownership information. This prevents consigned materials from being incorrectly converted into company-owned stock, improving inventory accuracy for manufacturing and consignment workflows.
Original PR description
**Problem:** when a MO is unbuild, if some components where consigned, they will come back in stock as not consigned **Steps to reproduce:** - enable "consignemnet" setting - create a storable…
**Problem:** when a MO is unbuild, if some components where consigned, they will come back in stock as not consigned **Steps to reproduce:** - enable "consignemnet" setting - create a storable product (the comp) - set on on hand quantity of 3 without owner - set on on hand quantity of 4 with an owner - create another product (the final product), with a BOM of 7 of the comp product - create a manufacturing order for the final product, confirm and produce all. - unbuild it - open the comp product form, click on the on hand smart button **Current behavior:** - there is a quantity of 7 unconsigned **Expected behavior:** - there should be a quantity of 3 unconsigned and a quantity of 4 consigned **Cause of the issue:** when the stock move line is create in action_unbuild() there is no mechanism to get back the owner of the original stock move line from the MO https://github.com/odoo/odoo/blob/ceccb92af19a6a3fc0c7b5924d9f497b1aec1d55/addons/mrp/models/mrp_unbuild.py#L204 opw-4900386 Forward-Port-Of: odoo/odoo#222491 Forward-Port-Of: odoo/odoo#219905
Leave requests can now be validated for employees who do not have a fixed working schedule. The system uses the employee resource timezone as a fallback, preventing errors and keeping time off approvals running smoothly.
Original PR description
Currently, if we try to validate a leave for a fully flexible employee (employee without a working schedule), we get a traceback when fetching the timezone from the working schedule. To rectify this issue, we default to the timezone of the resource. opw-4979974 Forward-Port-Of: odoo/odoo#222634
This fix prevents upgrade failures when one module changes a field to be company-specific and another module is updated later. It helps keep database upgrades reliable and reduces the risk of interruptions during module maintenance.
Original PR description
before this commit: if module_A has a field ``company_dependent=False`` and module_B override it to ``company_dependent=True`` When -u module_A, there would be an error since ORM tries to convert column type of the field from varchar/integer/boolean... to jsonb This commit will add a patch to the field in the ORM registry if the field was company dependent before upgrade. 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 Forward-Port-Of: odoo/odoo#222701 Forward-Port-Of: odoo/odoo#220983
Internal users without administrator rights can now send Spanish Facturae invoices without seeing an access error. The fix lets the system safely check the company certificate needed for sending, reducing blocked invoice workflows for affected users.
Original PR description
Non-admin users were hitting an “Access Error” when sending an invoice in facturae format, the onchange reads `company.l10n_es_edi_facturae_certificate_ids`, which reads certificate.certificate…
Non-admin users were hitting an “Access Error” when sending an invoice in facturae format, the onchange reads `company.l10n_es_edi_facturae_certificate_ids`, which reads certificate.certificate records , resulting in an “Access Error” popup. This changes Wrap the certificate lookup in company.sudo(). It's handled the same in https://github.com/odoo/odoo/blob/18.0/addons/l10n_es_edi_facturae/models/account_move.py#L140 https://github.com/odoo/odoo/blob/18.0/addons/l10n_es_edi_facturae/models/account_move.py#L770 install l10n_es_edi_facturae Go to Contacts and create an new contact with Spain as country in the same page (creating contact page) click on Accounting scroll down and set eInvoice format as facturaE Go to Accountant and create an invoice with that client pay the invoice log out and log in with a user with no administration (e.g. Marc demo) try to send the create invoice OPW:4989007 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222207
This fix prevents an error when users from one company browse an e-commerce website belonging to another company. It ensures the website can retrieve the correct company currency even when the browsing user does not have direct access to that company, improving reliability for multi-company setups.
Original PR description
A multi-company issue can occur when a user from another company tries to access products belonging to a different company. Steps to reproduce: 1. Create a e-commerce website without a pricelist on company A 2. Create a user assigned with only access to company B 3. Connect with this user and try to access the products on the website of company A An error will be raised because the user does not have access to company A. opw-4983506 Forward-Port-Of: odoo/odoo#222656 Forward-Port-Of: odoo/odoo#222457
This fix prevents an error when users press Enter while chat group search results are still loading. It improves reliability for users on slower networks by avoiding a crash during normal chat selection.
Original PR description
Description of the issue/feature this PR addresses: --- **Reason for PR** When a user searches for a chat group, if the network is slow and the search results have not yet been loaded, pressing **Enter** will cause the system to attempt to access the `unselectable` property of an `option` variable that is not yet initialized. This leads to the following error: ``` Uncaught Javascript Error: undefined is not an object (evaluating 'option.unselectable') ``` This PR adds handling to prevent the error when data has not been fully loaded. --- Current behavior before PR: https://github.com/user-attachments/assets/de3964c7-ff83-4f94-bc1a-cb8e09bfb62f --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222576
PDF reports covering multiple records now fall back to generating each document separately when the usual automatic splitting cannot be trusted. This prevents missing or incorrect PDFs for users, with a possible slowdown for large report batches.
Original PR description
When generating PDF reports with multiple records, the system tries to split the concatenated PDF using outlines. However, in cases where the number of outlines doesn't match the number of records or…
When generating PDF reports with multiple records, the system tries to split the concatenated PDF using outlines. However, in cases where the number of outlines doesn't match the number of records or outlines are missing, it falls back to generating individual PDFs per record by recursively calling `_render_qweb_pdf_prepare_streams()` for each `res_id`.
This ensures that each record gets its corresponding PDF even if splitting the combined PDF is not possible due to template or wkhtmltopdf inconsistencies.
issue related: https://github.com/odoo/odoo/issues/202299
Current Behavior:
The _render_qweb_pdf_prepare_streams method does not correctly generate PDF streams under specific conditions, causing the PDF to not be properly split for each res_id. When these conditions are met, the generated streams are set to None, resulting in incorrect PDF processing.
The issue occurs when all the following conditions are true:
reader.numPages != len(res_ids_wo_stream)
len(res_ids_wo_stream) > 1 and set(res_ids_wo_stream) == set(html_ids_wo_none) is True
not has_valid_outlines is False
has_same_number_of_outlines and has_top_level_heading is False, since has_same_number_of_outlines is False
Expected Behavior:
The method should correctly assign a valid PDF stream to each res_id, ensuring proper document splitting even when outlines cannot be used.
Steps to Reproduce:
Generate a PDF report where the number of pages does not match the number of res_ids.
Ensure that the report includes multiple records, and the outlines structure is not valid for splitting.
Debug and Observe that the streams assigned to res_ids are None, leading to issues in PDF rendering.
Error:
Odoo Server Error
RPC_ERROR
Odoo Server Error
Occured on 172.20.18.5:8069 on model ir.cron and id 31 on 2025-03-18 12:02:43 GMT
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 397, in safe_eval
return unsafe_eval(c, globals_dict, locals_dict)
File "ir.actions.server(309,)", line 1, in
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 5481, in _cron_account_move_send
self.env['account.move.send']._generate_and_send_invoices(
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 687, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 612, in _generate_invoice_documents
self._prepare_invoice_pdf_report(batch)
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 333, in _prepare_invoice_pdf_report
content_by_id = self.env['ir.actions.report']._get_splitted_report(pdf_report.report_name, content, report_type)
File "/home/odoo/src/odoo/addons/account/models/ir_actions_report.py", line 60, in _get_splitted_report
pdf_dict = {res_id: stream['stream'].getvalue() for res_id, stream in content.items()}
File "/home/odoo/src/odoo/addons/account/models/ir_actions_report.py", line 60, in
pdf_dict = {res_id: stream['stream'].getvalue() for res_id, stream in content.items()}
AttributeError: 'NoneType' object has no attribute 'getvalue'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/http.py", line 1962, in _transactioning
return service_model.retrying(func, env=self.env)
File "/home/odoo/src/odoo/odoo/service/model.py", line 156, in retrying
result = func()
File "/home/odoo/src/odoo/odoo/http.py", line 1929, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/odoo/src/odoo/odoo/http.py", line 2177, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
File "/home/odoo/src/odoo/odoo/http.py", line 727, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/odoo/src/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
File "/home/odoo/src/odoo/odoo/api.py", line 533, in call_kw
result = getattr(recs, name)(*args, **kwargs)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_cron.py", line 120, in method_direct_trigger
self.ir_actions_server_id.run()
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_actions.py", line 995, in run
res = runner(run_self, eval_context=eval_context)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_actions.py", line 827, in _run_action_code_multi
safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self)) # nocopy allows to return 'action'
File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 411, in safe_eval
raise ValueError('%r while evaluating\n%r' % (e, expr))
ValueError: AttributeError("'NoneType' object has no attribute 'getvalue'") while evaluating
'model._cron_account_move_send(job_count=20)'
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://172.20.18.5:8069/web/assets/0604b65/web.assets_web.min.js:3140:163)
at XMLHttpRequest. (http://172.20.18.5:8069/web/assets/0604b65/web.assets_web.min.js:3145:13)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#213900The contact geolocation action now handles unnamed sub-contacts without crashing. Users will see a normal no-match message instead of an error, making address lookup more reliable when contact records are incomplete.
Original PR description
<b>Steps to reproduce:</b> 1. Install base_geolocalize and Contacts > Go to Contacts. 2. Create a new contact or select an existing one (Individual). 3. Go to Contacts & Addresses > Add, leave all…
<b>Steps to reproduce:</b>
1. Install base_geolocalize and Contacts > Go to Contacts.
2. Create a new contact or select an existing one (Individual).
3. Go to Contacts & Addresses > Add, leave all fields empty, then Save & Close.
4. Open the newly created sub-contact > Partner Assignment > Geolocation
5. Click "Compute based on address".
<b>Issue:</b>
- Traceback is raised during geolocation computation if the sub-contact has no name Instead of Displaying.
<b>Cause:</b>
- If a partner does not have a name, the value is False.
- The join() operation results in a TypeError because False cannot be concatenated with strings.
<b>Problematic line:</b>
`'message': _('No match found for %(partner_names)s address(es).', partner_names=', '.join(partners_not_geo_localized.mapped('name')))`
<b>Solution:</b>
- Replaced `name` with `display_name` to ensure all elements passed to`join()` are strings.
This also improves readability in the UI when identifying partners without proper names.
opw-4930258
Forward-Port-Of: odoo/odoo#222317
Forward-Port-Of: odoo/odoo#218292This fix prevents Odoo from crashing when a user opens an app while multiple modules are still being installed. It makes the web interface handle partially loaded view information safely, improving reliability during installation workflows.
Original PR description
Currently, an error occurs when the user tries to install multiple modules and, during installation user tries to access any app. This issue happens because line [1] tries to get view info by view…
Currently, an error occurs when the user tries to install multiple modules and, during installation user tries to access any app. This issue happens because line [1] tries to get view info by view name, like `hierarchy`. Normally, we get the view information from the `_get_view_info` method (see [2]), and we override this method to add another view to the returned data (as in [3]). But during installation, when the user tries to access any app, the view is already loaded into the database. So when the `fields_get` method is called, the view is found. However, since the module isn't fully loaded yet, the overridden `get_view_info` method hasn't taken effect. As a result, the additional view we expect isn’t included, and accessing that view key causes an error. This commit fixes the above error by ensuring that `_view_info` is accessed only when `type_` is present in `_view_info` at [1]. [1]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web/models/ir_ui_view.py#L14 [2]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web/models/ir_ui_view.py#L22-L31 [3]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web_hierarchy/models/ir_ui_view.py#L56-L57 sentry-5661154820 Forward-Port-Of: odoo/odoo#221847
Saudi e-invoicing QR codes now use the actual amount due on each invoice instead of the total sale order amount. This prevents ZATCA warnings on regular invoices following down payments and helps invoices be accepted cleanly.
Original PR description
#### Step to reproduce: - In a company in Saudi Arabia - Create a sale order to a customer (B2C) - Create an invoice as a downpayment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) - Create an invoice as a regular payment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) #### Current behavior: - ZATCA return a 200 code for the downpayment invoice. - ZATCA return a 202 code with a Warning for the regular payment invoice. The warning states that the invoice was accepted however it needs the Tag 4 of the QR code to be Amount due payment (BT-115) #### Expected behavior - ZATCA return a 200 code on both invoices. opw-4848578 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219464
This fix ensures Point of Sale loyalty rewards correctly recognize price list settings when applying reward conditions. It prevents loyalty options from being missed during sales or refunds, helping keep customer rewards consistent.
Original PR description
Task: [#4974070](https://www.odoo.com/odoo/my-tasks/4974070) Runbot build error: [#229672](https://runbot.odoo.com/odoo/runbot.build.error/229672) --- ## Error FAILED: [12/46] Tour…
Task: [#4974070](https://www.odoo.com/odoo/my-tasks/4974070)
Runbot build error: [#229672](https://runbot.odoo.com/odoo/runbot.build.error/229672)
---
## Error
FAILED: [12/46] Tour test_refund_does_not_decrease_points → Step selection popup has '$ 1 per point on your order' (trigger: .selection-item:contains("$ 1 per point on your order")).
## Qualifiers
{
"module": "pos_loyalty",
"test_path": "/pos_loyalty/tests/test_frontend.py",
"tour_name": "test_refund_does_not_decrease_points",
"tour_step": ".selection-item:contains(\"$ 1 per point on your order\")",
"test_class": "TestUi",
"test_method": "test_refund_does_not_decrease_points",
"test_module": "pos_loyalty"
}
## Fix
In some cases, the POS config's `pricelist_id` was not available in the frontend, causing loyalty program conditions to be skipped when checking for a matching pricelist.
By explicitly setting `use_pricelist` to True on the POS config, we ensure that `config.pricelist_id` is properly loaded and available at runtime, allowing loyalty programs with pricelist conditions to behave as expected.Employees assigned to recurring tasks in private projects can now mark those tasks as done without seeing an access error. This ensures private project permissions are respected while allowing normal task completion workflows to continue.
Original PR description
to reproduce: ============= - create a private project and a recurrent task in it - assign the task to an employee - log in as the employee - mark the task as done - the task should be closed but it is not and the employee gets an error Problem: ======== while changing the state of a recurrent task, we need to read the project which is not allowed for this employee since the project is private. Solution: ======== we need to use sudo() to read the project in this case. opw-5012231 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Editing quantities on receipts for products valued by lot now avoids an unexpected system traceback. Users get the intended handling or a clear error when lot information is missing, helping warehouse and purchasing teams correct the issue without disruption.
Original PR description
Steps to reproduce: 1) Create a product tracked by lot and with valuation by lot. 2) Create a Purchase Order with this product and Confirm it. 3) Go to Receipt 4) Add a Lot number and validate 3) Unlock the receipt and modify the `quantity`. Current behavior - Get a traceback. Expected behavior: - If there is only one lot: - update the lot quantity - Else : - raise an error The fix should be applied before the `web_save` call to prevent the creation of a new `stock.move.line`. Therefore it's done on the `onchange` call. opw-4841162 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221620 Forward-Port-Of: odoo/odoo#213534
Calendar reminders are now limited to upcoming events within the correct reminder window. This prevents users from receiving outdated notifications for recurring meetings that already happened, reducing confusion and improving reminder reliability.
Original PR description
Steps to reproduce the issue: 1. Create a calendar event (meeting, for example) 2. Set the start date as yesterday and in 30 minutes from now. 3. Set it to be recurrent every week with end_type set…
Steps to reproduce the issue: 1. Create a calendar event (meeting, for example) 2. Set the start date as yesterday and in 30 minutes from now. 3. Set it to be recurrent every week with end_type set to end_date and in the future(1 month from now). 4. Add a reminder to the event (30 mins, for example) and ensure that calendar_last_notif_ack is set before the alarm window for your user's res.partner. 5. Save the event and observe an alarm notification made for an event in the past. After the fix, the calendar alarms will only trigger for events in the future and in their designated time windows. The recurrence logic was also removed from the query to align with this [[REF]](https://github.com/odoo/odoo/pull/42031/commits/a27afdb5434166c3ea48c18ccfba9e8245d18e62) since recurring events are all persistent records in the database. opw-4776638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222610 Forward-Port-Of: odoo/odoo#222214
Physical Inventory no longer shows a duplicate serial number warning after an item with a unique serial number is moved between locations. This avoids unnecessary confusion for warehouse users and helps keep inventory adjustments focused on real stock issues.
Original PR description
## Issue: ## A warning appears in Physical Inventory when transferring a product with a serial number between two locations ## Cause: ## The `_compute_sn_duplicated()` method incorrectly considered…
## Issue: ## A warning appears in Physical Inventory when transferring a product with a serial number between two locations ## Cause: ## The `_compute_sn_duplicated()` method incorrectly considered `stock.quant` records with quantity 0 That mean that it will considered a duplication even if the quant indicate that the product isn't in that location Additionally, the system parameter `stock.skip_quant_tasks` is enabled on all SaaS environments since version 18.2 It was added for performance issues: (see: https://github.com/odoo/odoo/commit/207ba01819577cf6a2a686fae39dd3d673aec6dd) When enabled, the quant merging and removal of zero quants are skipped when opening a Physical Inventory, causing this issue to appear ## Steps to reproduce: ## - Enable Developer Mode - Create a New System Parameter (Key: stock.skip_quant_tasks, Value: True) - In Settings, enable Storage Locations and Lots & Serial Numbers - Duplicate WH/Stock as WH/Stock (copy) - Create a product tracked by Unique Serial Number - Update its quantity: one at WH/Stock - Process an Internal Transfert from WH/Stock to WH/Stock (copy) - Go in Operations > Adjustments > Physical Inventory opw-4944011 Forward-Port-Of: odoo/odoo#221578
This fix prevents an error when users group Cash Flow report data by account code. It helps ensure financial reports remain usable even when account line data includes a custom account code field.
Original PR description
The term used by GROUP BY should be the same term in the SELECT, avoiding the posible error like: ERROR: column "account_move_line__account_id.code_store" must appear in the GROUP BY clause or be used in an aggregate function That appears when a column named account_code is created for the model account_move_line. opw-4963180 Forward-Port-Of: odoo/enterprise#91915
This update ensures Point of Sale totals in Mexican electronic invoicing are rounded using the currency's correct precision. It prevents valid fully discounted orders from being blocked by a validation error caused by tiny rounding differences.
Original PR description
Issue: With specific prices and discounts, we can get an rounding issue that does not pass the Validation Error. Purpose of this PR: To round the amount total based on the currency's rounding precision to pass the check. Steps to Reproduce on Runbot: install pos, l10n_mx create products prices with 75.00 and 60.00 respectively. create discount 100% on order change decimal accuracy to 3, change tax to Include with Price create PoS order with products and apply discount receive ValidationError even though the amount total should be rounded to 0.0. opw-4944830 Forward-Port-Of: odoo/enterprise#92141
Activity filters now focus on each user's own next activity deadline instead of mixing in deadlines from other users on the same record. This makes late, today, and future activity counts and filtered lists match more reliably across business apps.
Original PR description
Partially revert [1] as users expect to see the deadline of their next activity, matching the count displayed in the systray menu. Currently clicking "late activities" for example will show you all records with *any* late activity, instead of records where you personally have late activities. As the more common use case is to view your own activities, that should be what the filter shows. Users may create their own filters to find records based on the next overall deadline. [1]: ad95d7d42f195527bbaccdf349da8316e9c9df12 task-4988330
This fix ensures the payment widget shows the correct remaining bank statement amounts after partial reconciliation and applies the right currency conversion for multi-currency payments. It also prevents removing unrelated invoice matches when undoing one partial payment, reducing accounting errors and manual corrections.
Original PR description
[FIX] account_accountant: fix multi_currency payment_widget To reproduce: - Make a statement line for partner_a for 200 $ - Make an invoice for same partner for 100 $ - Reconcile it with the…
[FIX] account_accountant: fix multi_currency payment_widget To reproduce: - Make a statement line for partner_a for 200 $ - Make an invoice for same partner for 100 $ - Reconcile it with the statement line - Duplicate the invoice and post it => First issue, you don't see the 100$ left on the statement line It's still reconciliable To fix that, we only remove fully reconciled statement lines. Second issue: - Have a bank journal in EUR with a rate of 2 - Make a statement line for 400€ in this journal - Create an invoice for the same partner of 100$ => The widget proposes a statement line of 400$ instead of a 200$ equivalent (with the rate conversion) The issue is that we convert with a foreign_currency_id that is not present in that case. To fix both, we change the way we compute the amount to always use the residual converted from the right currency [FIX] account_accountant: partial on statement line for invoice widget To reproduce: - Make a statement line for partner_a for 200 $ - Make 2 invoice for same partner for 100 $ - Reconcile them with the statement line (via the widget) - Unreconcile first invoice via the payment widget => The second invoice is also unreconciled To solve: Only unreconcile the lines that are part of the partial that we want to unlink
This fixes an error that could block customers from adding a new address during website checkout when the company is configured for Colombia. The checkout form now handles the identification type field correctly in all display modes, improving reliability for Colombian eCommerce flows.
Original PR description
To reproduce: ============= 1- Install Colombia accounting 2- Install eCommerce 3- Set company address to Colombia 4- Go to website and add item to cart 5- Checkout & click "Add new address" →…
To reproduce: ============= 1- Install Colombia accounting 2- Install eCommerce 3- Set company address to Colombia 4- Go to website and add item to cart 5- Checkout & click "Add new address" → Traceback occurs Problem & Solution: =================== The field l10n_latam_identification_type_id is always present in the address form but its HTML element changes: it's rendered as a `select` when is_commercial_address and can_edit_vat is true, and as an `input` otherwise. The JS code only looked for the `select`, so when the `input` was rendered instead, the selector was null and caused a traceback. Update the selector to look for the field in either `select` or `input` form, so the code works regardless of the rendering conditions. useful-links: https://github.com/odoo/odoo/blob/4806b08dcfc965cdbd463269be078f8da9f48863/addons/l10n_latam_base/views/portal_address_templates.xml#L10-L11 https://github.com/odoo/odoo/blob/4806b08dcfc965cdbd463269be078f8da9f48863/addons/l10n_latam_base/views/portal_address_templates.xml#L32-L33 opw-4969089
The portal now shows total task hours based only on validated timesheets when that invoicing policy is selected. This keeps the displayed total consistent with the visible timesheet lines and avoids overstating billable or reported work.
Original PR description
### Steps to reproduce: - Set timesheets inovicing policy to 'Validated Timesheets Only' - From the portal go to any task that has some validated timesheet and some other not - Notice that the lines…
### Steps to reproduce: - Set timesheets inovicing policy to 'Validated Timesheets Only' - From the portal go to any task that has some validated timesheet and some other not - Notice that the lines shown is the validated ones only but the Hours spent includes the non-validated ones too ### Current behavior before PR: The total hours spent for timesheets in portal view when setting the invoicing policy to 'Validate Timesheets Only' is calculated wrongly as it takes the non validated ones into account. This is happening as when passing the values to the view we pass 'task_sudo' variable which will have the SUPERUSER as the env.user https://github.com/odoo/odoo/blob/saas-17.2/addons/project/controllers/portal.py#L569 so it won't pass the condition if the user is portal or not https://github.com/odoo/enterprise/blob/saas-17.2/sale_timesheet_enterprise/models/project_task.py#L33:L35 and it will calculate all the timesheet without taking validation into condisderation. ### Desired behavior after PR is merged: As we are using those computed fields only in portal views so we don't have to check if the user is portal user as even if an internal user is showing the same view for testing he should be able to see the same data as the portal user. opw-4193842 Forward-Port-Of: odoo/enterprise#70557
Fixed an issue in the Spanish SME Balance Sheet where certain group company investment accounts could be counted twice, making reported amounts appear doubled. This improves the accuracy of Spanish financial reporting for affected companies.
Original PR description
Issue: - Amounts were exactly doubled in 'Current Investments in Group Companies and Associates' in the Spanish Balance Sheet - SMEs report as account codes 5523 and 5524 were incorrectly added to…
Issue: - Amounts were exactly doubled in 'Current Investments in Group Companies and Associates' in the Spanish Balance Sheet - SMEs report as account codes 5523 and 5524 were incorrectly added to multiple balance sheet sections Root Cause: - Account codes 5523% and 5524% were included in BOTH: 1. 12400 (Assets): 'Current investments in group companies' 2. 32400 (Liabilities): 'Group companies current liabilities' - This double-counting caused investment amounts to appear twice in the balance sheet How to Reproduce: 1. with Spain - SMEs Fiscal Localization's Package 2. Go to Accounting -> Configuration -> Journal -> Bank 3. Change suspense account to code 5523X or 5524X (should be added to chart of accounts before) 4. Post journal entries to accounts 55230X or 55240X 5. Generate 'Balance Sheet - SMEs (ES)' report 6. Observe amounts are exactly doubled compared to account balances Fix: - Removed duplicate account codes from balance_pymes_line_12400_sub_balances - These accounts are properly handled by the domain formula in line 32400 - Each account code now appears in only one balance sheet section" opw-4983300
The default Swiss payroll setting for the contractual 13th month payment rate has been adjusted from 8.33% to 8.3333%. This improves payroll calculation accuracy for Swiss employment contracts and helps reduce rounding differences.
Original PR description
-changed the default contractual thirteen month rate for Switzerland from 8.33 to 8.3333 Forward-Port-Of: odoo/enterprise#92129 Forward-Port-Of: odoo/enterprise#92095
Internal users can now see the Documents app button, making it easier to access shared documents from the main app menu. This also clarifies that users do not need the full Documents User role to access documents shared with all internal users.
Original PR description
The app is accessible to all internal users via smart buttons and their portal already, showing the button is helpful in two ways: 1/ Easier access to the app, duh. 2/ Makes it explicit that you don't need to be a "Documents User" to have access to documents shared with all **internal users**, even those that are not documents user (that didn't have the app button available). In 18.0 so that new installations have it. Task-4889053 Forward-Port-Of: odoo/enterprise#92124 Forward-Port-Of: odoo/enterprise#90937
The Argentina electronic invoicing test setup now stops after a limited number of failed connection attempts instead of retrying indefinitely. This reduces wasted time and lowers the risk of external services blocking repeated automated test requests.
Original PR description
In 18.0 and above test hasn't worked in months, half the time it fails because pretty much nothing works in it and half the time it's because it keeps looping on trying to set up the connection and failing (possibly because we're getting blacklisted due to how much spamming we do). For now restrict to just trying 5 times (per class since it's called from a `setUpClass`) with an exponential backoff. This may yet end up in removing the entire test directory as it doesn't seem like anyone cares. Forward-Port-Of: odoo/enterprise#92226 Forward-Port-Of: odoo/enterprise#92207
This fix ensures subscription effective dates set during order processing are properly saved to the database. It prevents cases where the date could appear set internally but not be persisted, improving reliability for subscription records.
Original PR description
Since https://github.com/odoo/enterprise/commit/ff8e55ed83d4905584b7ea10b60ded0d7afbd0cf setting the effective date is done in a precommit hook. Problem, the precommit don't automatically flush. The value set in the cache may be never reflected in the database. Solution: Explicitly flush in the precommit hook
Belgian Group S payroll exports now use the company selected by the user when multiple companies are active, instead of only the current company. The export also checks that the required Group S company code is set before proceeding, helping prevent incomplete or rejected work entry exports.
Original PR description
before this commit only the current company was taken into account when exporting work entries now another company can be selected if multiple companies are active for the current user In addition to that this commit also add a check for the company's group s code to enforce the user to set it before exporting work entries task-4213675 closes old PR: odoo/enterprise/pull/71521 Forward-Port-Of: odoo/enterprise#89438
Fixed an issue where exporting the Journal Audit report to PDF could fail when filtering by receivable or payable account types. This ensures finance teams can generate audit PDFs reliably with those filters enabled.
Original PR description
- In the Journal Audit report options, set the Account Type (filter_account_type) to either receivable, payable, or both. - Attempt to export the PDF of the Journal Audit report. A traceback occurs because, in _generate_document_data_for_export, we attempt to add a join using an alias. However, if the filter_account_type option is enabled, there is already a left join in the query with the same alias: account_move_line__account_id. opw-4926547 Forward-Port-Of: odoo/enterprise#91683
Tickets created from timesheets now default to the helpdesk team linked to the selected project. This prevents new tickets from being assigned to the wrong team and limits team choices to teams that support timesheets.
Original PR description
Steps to Reproduce: - 1. Go to Timesheets > My Timesheets, start the timer, and select the project linked to the helpdesk team. 2. In the timer header, quick-create a new ticket via the "Ticket" field dropdown 3. Observe that the default helpdesk team on the new ticket is incorrect. Issue: - - When creating a ticket from the Timesheets module (e.g., via timer header or views), the system selects an incorrect default helpdesk team, leading to misassigned tickets. Cause: - - The core default logic for team_id prioritizes user membership or the first team without considering the selected project's linked helpdesk team. Fix: - - Override `_default_team_id` to set the correct Helpdesk Team based on the selected project. - A domain has been added to the team selection field within the timesheet views to only show teams that have the timesheet feature enabled. task-4885679 Forward-Port-Of: odoo/enterprise#92112 Forward-Port-Of: odoo/enterprise#89503
15 changes
Resolved issues and error corrections
This fixes a date-sensitive automated test in the Time Off module by ensuring all related logic runs with a fixed date. It helps prevent false test failures caused by the current calendar date, improving reliability for future updates.
Original PR description
Given that accrual plans are related to dates, all the testcase logic has to be inside 'with freezetime' to avoid date related errors Runbot-error: https://runbot.odoo.com/odoo/runbot.build.error/230722
This fix ensures Spanish POS orders follow the correct Veri*Factu workflow: eligible orders can be sent after session closing, already registered orders no longer show an unusable send option, and cancellations are blocked in favor of refunds. This helps businesses avoid unsupported compliance actions and reduces confusion for staff handling Spanish electronic reporting.
Original PR description
- The "Send Veri*Factu" button is currently also visible for registered orders (but we can not send documents for such orders anyway; we do not support subsanacion) - We do not allow generating Veri\*Factu documents for posted orders. That makes it impossible to (Veri\*Factu) send orders after the session is closed. - We should not allow to Veri*Factu cancel orders. They would still be included in the closing move. The user should create refund instead. task-None Forward-Port-Of: odoo/odoo#222668
This fixes an intermittent failure in mail-related automated tests by making them wait properly for asynchronous server responses. It helps keep the validation pipeline stable, especially when test servers are under heavy load, without changing user-facing behavior.
Original PR description
These tests were failing due to `expect.verifySteps()` being empty rather than the RPC response. The rpc response is asynchronous and awaiting the click doesn't necessarily mean the RPC had time to effectively happen, especially when runbot CPU load is high. Fixes runbot-error-160954
Point of Sale now applies the same tax treatment in the user interface as in the backend when an order includes a negative line. This prevents mismatched totals and helps avoid accounting entries becoming unbalanced.
Original PR description
Before this commit, when an order contained a negative line, the backend treated it as a refund line while the POS UI did not. This mismatch caused inconsistent tax calculations between the UI and the backend, which could result in unbalanced journal entries. With this commit, the tax calculation logic is aligned between the UI and the backend, ensuring consistency and preventing unbalanced moves. opw-4972314 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change adjusts an automated test for the HTML editor so it opens the font size menu in a more consistent way. It helps reduce intermittent test failures, improving confidence in release validation without changing user-facing behavior.
Original PR description
The fix at [1] fixed the case when the dropdown had not yet opened, but that was not really the cause of the issue here. It's unclear to me what is the issue exactly, but I've noticed this particular test did open the font size dropdown in a slightly different way than other tests which do not have the same non-deterministic issue. runbot-230945 [1]: https://github.com/odoo/odoo/pull/222583
This change improves the reliability of an automated test for public discussion channels by ensuring the page has fully reloaded before the test continues. It helps reduce false failures in validation systems, making releases and maintenance checks more dependable without changing user-facing behavior.
Original PR description
This test suspiciously fails in various ways in all versions before the following PR: https://github.com/odoo/odoo/pull/214358 This seems to indicate an issue with the page reload. Properly wait for the page to reload before proceeding with the next steps in the tour, hoping it will resolve all the related issues. https://runbot.odoo.com/odoo/error/111051 https://runbot.odoo.com/odoo/error/223165 https://runbot.odoo.com/odoo/error/227755 https://runbot.odoo.com/odoo/error/227756 https://runbot.odoo.com/odoo/error/227757 https://runbot.odoo.com/odoo/error/227758 https://runbot.odoo.com/odoo/error/229657 https://runbot.odoo.com/odoo/error/229724 https://runbot.odoo.com/odoo/error/229745 https://runbot.odoo.com/odoo/error/229817 https://runbot.odoo.com/odoo/error/230901
Partner autocomplete now uses standard industry codes instead of internal database IDs when receiving Dun & Bradstreet data. This prevents errors when a customer has customized, removed, or recreated industry records in their Odoo database, improving reliability during company data enrichment.
Original PR description
Ticket #4992568 highlighted a weird way of sending the industry from IAP to the Odoo client. Before this commit, we were sending the IAP psql id of the industry to the client. There, it would be use as is. It works because these industries haven't been changed in years and they're created in the same order. However the ticket highlighted the fact that a user can edit/delete/create its own industries, therefore some ids that exist on IAP might not exist on the client's Odoo instance. This resulted in a traceback on the client's side. With this commit, we now send the industry code (the ISIC: International Standard Industrial Classification) instead to the client. There it can correctly be mapped if it exists on the client's DB (e.g. not deleted) opw-4992568 https://github.com/odoo/iap-apps/pull/1152 Forward-Port-Of: odoo/odoo#222486
Calendar meetings that do not have an assigned organizer are now shown correctly when users group the list by responsible person and creation date. This prevents valid meetings from being hidden, improving visibility and reliability for calendar planning.
Original PR description
__Issue__ In the calendar list view, meetings with no organizer and default privacy (`privacy=False`) are excluded when grouping by Responsible and Created On. __Steps to Reproduce__ 1. Create a meeting with: - `privacy` set to default, - no `organizer` 2. Go to Calendar > List view. 3. Group by Responsible, then by Created On. → The meeting is missing from the view. __Fix__ Adjust the domain to include meetings where: - `privacy=False`, and - either `user_id` is unset or their settings are in the public allowed list. - opw-4841266
This fixes sales reporting for Point of Sale orders when the same product appears on multiple order lines and is shipped later. Delivered quantities are now split correctly across the lines, preventing inflated totals such as reporting 16 delivered instead of 8.
Original PR description
If you made a sale with multiple lines having the same product, the qty_delivered was not correctly computed on the different lines. Steps to reproduce: ------------------- * Activate the ship later…
If you made a sale with multiple lines having the same product, the qty_delivered was not correctly computed on the different lines. Steps to reproduce: ------------------- * Activate the ship later option in the PoS settings * Open PoS * Add any product with a quantity of 5 * Apply a discount of 20% to the line * Click on the same product so that they are added as a second line * Change the quantity of the second line to 3 * Validate the order and use the ship later option * Validate the picking * Go to the sale report and check the qty_delivered for the product > Observation: The qty_delivered is doubled, 16 instead of 8. Why the fix: ------------ The qty_delivered was computed by summing the quantities of all moves for the product, but it did not take into account that the same product could be present in multiple lines of the same order. We now make sure to dispatch the delivered quantity correctly across the different lines of the order, ensuring that the qty_delivered is accurate. opw-4826487
This fix prevents an error when users duplicate multiple Point of Sale configuration records from the list view. It allows the duplication action to complete reliably for more than one selected record, improving day-to-day administration of POS settings.
Original PR description
### Steps to reproduce the issue: 1) In the Point of Sale app, when trying to duplicate more than two records from the list view, it gives a singleton error. The implementation was added to the master branch from commit [1]. [1]: https://github.com/odoo/odoo/pull/92664/files#diff-4c6e412c7d8f4df2a05831547e7df93d0b91f510d03b7b3ed0d689a18f5dae44R360-R361 opw-4969713 ### Description of the issue/feature this PR addresses: #### Issue Previously, when duplicating more than one pos.config record, it would give a singleton error. #### Solution Added a for loop to iterate over the config records individually. ### Current behavior before PR: https://github.com/user-attachments/assets/ba5a3969-7647-4943-a0b1-12b1961f26cd ### Desired behavior after PR is merged: https://github.com/user-attachments/assets/b952b711-7782-4e9d-b05a-e4019ab79d87 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale now plays the expected error sound when an unknown barcode is scanned, alongside the on-screen warning. This restores feedback that helps cashiers quickly notice failed scans and matches behavior from earlier Odoo versions.
Original PR description
When scanning an unknown barcode, the error notification pop-up is displayed, but the error sound is not played. Steps to reproduce: ------------------- * Open PoS * Scan an unknown barcode > Expected: Both the 'BIP' and the error sound should play. Why this fix: ------------- This feature was present in 16.0 and 17.0, but was lost in 18.0 REF. It was reintroduced in 18.3 with this [IMP](https://github.com/odoo/odoo/pull/209478). opw-4987066 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where custom readonly fields on invoice lines could still be changed, causing invoices to appear modified unexpectedly. The readonly override is now limited to the intended invoice line fields, preserving user-defined protections in Studio.
Original PR description
Steps to reproduce ================== - Go to invoices - Open studio - Click on the invoice lines - Edit the list view - Add a new field of type checkbox - Mark that field as readonly - Exit studio - Open an invoice - Click on the checkbox => The form is marked as dirty and the checkbox is toggled Cause of the issue ================== https://github.com/odoo/odoo/commit/291518a7e7708690d183b9d1ca53c84d0c56ad90 If the state is not in ["cancel", "done", "posted"], the fields are never in readonly Solution ======== Only do this for the "name" and "product_id" fields opw-4917471
Uninstalling the Marketing Card module could leave behind database leftovers and block clean reinstallations. This fix skips unnecessary cleanup during module removal so uninstall and reinstall operations complete reliably.
Original PR description
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for…
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for uninstallation, all its fields get removed first (because that's how `_module_data_uninstall` does things), so all the non-magic columns are dropped. Then, when trying to `unlink` the `ir.model` records the `unlink` call fails with some sort of "column does not exist" error (on `active` or `res_model`), the unlink fails, which leads the tables to not be removed, leaving a ton of garbage in the database. This in turns means trying to reinstall the module also fails, as many tables will have a few records left for one reason or another before they are dropped, so new columns which are `required` without a `default` fail to set up their constraint, which logs both errors and warnings on reinstall. None of this is necessary, if `marketing_card` is being uninstalled we can just ignore the entire issue as the table should be dropped eventually, even if it worked it would be a waste of time. https://runbot.odoo.com/odoo/error/230837
This fix prevents an error when a user presses Enter while chat group search results are still loading on a slow connection. It makes the mail chat search experience more reliable and avoids an unexpected interruption for users.
Original PR description
Description of the issue/feature this PR addresses: --- **Reason for PR** When a user searches for a chat group, if the network is slow and the search results have not yet been loaded, pressing **Enter** will cause the system to attempt to access the `unselectable` property of an `option` variable that is not yet initialized. This leads to the following error: ``` Uncaught Javascript Error: undefined is not an object (evaluating 'option.unselectable') ``` This PR adds handling to prevent the error when data has not been fully loaded. --- Current behavior before PR: https://github.com/user-attachments/assets/de3964c7-ff83-4f94-bc1a-cb8e09bfb62f --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222576
Saudi e-invoice QR codes now use the amount due on the specific invoice instead of the full sales order total. This prevents ZATCA warnings on regular invoices after down payments and helps invoices be accepted cleanly.
Original PR description
#### Step to reproduce: - In a company in Saudi Arabia - Create a sale order to a customer (B2C) - Create an invoice as a downpayment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) - Create an invoice as a regular payment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) #### Current behavior: - ZATCA return a 200 code for the downpayment invoice. - ZATCA return a 202 code with a Warning for the regular payment invoice. The warning states that the invoice was accepted however it needs the Tag 4 of the QR code to be Amount due payment (BT-115) #### Expected behavior - ZATCA return a 200 code on both invoices. opw-4848578 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219464