Thursday, July 9, 2026
31 changes · saas-19.3
Resolved issues and error corrections
GIFs shared in Facebook comments now appear in the social feed comments view instead of showing as missing content. Since Facebook provides a still image and video link rather than the original GIF, users see the preview image and can open the animated version on Facebook.
Original PR description
Bug === When opening the comments modal of the feed view, the GIF images are not visible. Technical ========= The API does not return the GIF, it only returns the MP4 and the JPG. So we show the fixed image, and when clicking on it, it opens the video on Facebook. Task-6241607 Forward-Port-Of: odoo/enterprise#123181 Forward-Port-Of: odoo/enterprise#118619
Downloading a Knowledge article as a PDF now produces a cleaner document without unwanted scrollbars or open menu overlays. This makes exported articles easier to read and more suitable for sharing or archiving.
Original PR description
The Download PDF option of an article prints the page with the browser. On screen, the article body is inside .o_scroll_view_lg, which scrolls when the content is longer than the screen:…
The Download PDF option of an article prints the page with the browser. On screen, the article body is inside .o_scroll_view_lg, which scrolls when the content is longer than the screen: https://github.com/odoo/enterprise/blob/79f8defa04476e1b939dc8bb5449a775137aed62/knowledge/static/src/scss/knowledge_views.scss#L170-L177 The print stylesheet used to force overflow: visible on every div, so this container did not scroll when printing. It also hid every child of the body except the action manager, so the navbar and open dropdowns were left out of the print. Commit https://github.com/odoo/enterprise/commit/69612c80ea0aec5ccf2c2857449da03e61273457 rewrote knowledge_print.scss to scope its rules to the Knowledge view and removed both rules. The scroll container now keeps its fixed height and its scrollbar when printing, so the scrollbar is drawn in the print preview and on every page of the PDF. The dropdown opened to reach Download PDF is printed on top of the article when it overlaps the page area, which happens when the browser is zoomed in. Add overflow: visible to the print rule of knowledge_print.scss that already targets .o_scroll_view and .o_scroll_view_lg with position: static. That rule exists to undo the screen positioning of the scroll containers when printing, so the overflow reset belongs there. Its selector is also more specific than the screen one, so the value applies without !important, like position: static already does. Restore the rule that hides the body children other than the action manager, scoped to the Knowledge view like the rest of the file since the print stylesheet is now loaded on every page. Before: <img width="497" height="703" alt="image" src="https://github.com/user-attachments/assets/44aa3366-3fc8-4382-8aa2-84625fa4b6d8" /> After: <img width="497" height="703" alt="image" src="https://github.com/user-attachments/assets/8b6eb2bc-37a3-4666-b871-0e6149c41fea" /> Steps to reproduce: 1. Open the Knowledge app and create an article 2. Paste enough text in the article to fill more than one PDF page 3. Zoom the browser to 200% 4. Click the three dots in the top right corner, then Download PDF 5. Check the print preview or the saved PDF => A scrollbar is drawn on the right edge of every page and the dropdown menu is printed on top of the article Ticket [link](https://www.odoo.com/odoo/project.task/6279174) opw-6279174 Forward-Port-Of: odoo/enterprise#120249
This update restores a missing text message in the Stripe expense integration. It helps ensure users see the intended guidance or notification instead of an incomplete or deprecated message.
Original PR description
Add missing string runbot-941402 Forward-Port-Of: odoo/enterprise#123495
The POS due settlement flow now only runs India-specific invoice checks when the company is actually in India. This prevents unnecessary errors in other countries and improves reliability of the payment screen.
Original PR description
Toggle invoice button was making a call in IN localization even when not in a IN country. This was causing an error in runbot 940146. This commit fixes the issue by checking if the country is IN before making the call. In `pos_settle_due` the method signature was not correct. Forward-Port-Of: odoo/enterprise#123539
The Sendcloud delivery test suite was corrected so it no longer gets skipped from standard continuous integration checks. This helps catch related issues earlier, before they reach nightly testing or later release stages.
Original PR description
Test class was tagged as external although calls are mocked. This means errors were only caught in nightly and not by CI. Removing the tag requires fixing some of the tests. Forward-Port-Of: odoo/enterprise#121404 Forward-Port-Of: odoo/enterprise#111660
This fixes an error that could block Belgian tax return setup when sales data included checks related to Northern Ireland customers. Businesses can generate affected VAT returns more reliably without unexpected tracebacks.
Original PR description
…mers Steps to reproduce: - Setup a Belgian company - Make a sale to a French customer in June for example - Setup the tax returns (so that June returns are generated) -> Traceback raised from the check on sales done to customers from North Ireland.
Helpdesk will no longer send automatic closing reminder emails to tickets that are not eligible for automatic closure. This prevents customers from receiving misleading warnings about tickets that will not actually be closed.
Original PR description
**Problem:** When a team restricts automatic closing to specific stages (from_stage_ids), the closing-reminder email is still sent to every inactive ticket in the team, including tickets in stages…
**Problem:** When a team restricts automatic closing to specific stages (from_stage_ids), the closing-reminder email is still sent to every inactive ticket in the team, including tickets in stages that are never auto-closed. **Steps to reproduce:** 1. On a helpdesk team, enable Automatic Closing with a reminder and set "In Stages" (from_stage_ids) to one specific stage 2. Leave a ticket inactive in a different, non-folded stage until it reaches the reminder threshold (auto_close_day - reminder_delay) **Current behavior:** The ticket gets a "your ticket will be closed soon" reminder even though it is not in an auto-close stage and will never be closed. **Expected behavior:** Only tickets that would actually be auto-closed (those in from_stage_ids) should receive the reminder. **Cause of the issue:** The reminder selection filters on auto_close_ticket_reminder and the reminder date only; unlike the auto-close selection, it does not apply the team's from_stage_ids condition. **Fix:** Reuse the same stage condition used to select tickets for closing when selecting tickets for the reminder, so the reminded set stays consistent with the set that will be auto-closed. opw-6291237 Forward-Port-Of: odoo/enterprise#120732
Payroll warning rules for Belgian payroll now apply the correct filters, preventing access errors from appearing for items outside the Belgian payroll scope. This helps payroll users work without avoidable interruptions when reviewing warnings.
Original PR description
Some payroll warnings in BE were missing correct filtering to avoid access errors on things outside of the BE scope.
This update changes when a field service sales timesheet test runs so it avoids accounting setup warnings and unstable results. It also skips the check when an optional stock-related module changes the expected behavior, helping keep automated validation reliable without affecting users.
Original PR description
Before this commit, the `TestFsmFlowSaleAtInstall.test_fsm_flow` test throws a warning because of chart template in accounting, the reason is because all tests using accounting test class have to be executed in post_install to avoid having unexpected issue. This commit moves the test in post_install and skip the test is `planning_field_service_sale_stock` module is installed because the behavior tested is altered when that module is installed. runbot-error-240998 Forward-Port-Of: odoo/enterprise#122306
This update ensures the Frontdesk app includes the required scheduling view component it relies on. It helps prevent setup or display issues when using Frontdesk planning features.
Original PR description
runbot-237869 Forward-Port-Of: odoo/enterprise#122292
Canadian check stubs now follow the same setting as the check itself when using pre-numbered check stock. This prevents duplicate or unwanted check numbers from appearing on stubs, improving printed check accuracy and consistency.
Original PR description
The check itself respected the check_manual_sequencing field, but the stubs did not. Hide the numbers on stubs as well, exactly like on US checks. task-6343701 Forward-Port-Of: odoo/enterprise#122565
This change prevents an error when users try to split a completed stock transfer that no longer has any remaining quantity. Instead of triggering a traceback, the system now safely does nothing, which preserves the expected behavior and avoids disruption.
Original PR description
Issue before this commit: ========================= When splitting a done picking that contains at least one stock move whose done quantity is less than the demanded quantity (product_uom_qty), an…
Issue before this commit: ========================= When splitting a done picking that contains at least one stock move whose done quantity is less than the demanded quantity (product_uom_qty), an expected singleton traceback occurs. Steps to Reproduce: ========================= - Install the stock module with demo data. - Create a delivery picking for any product with a demand of 5. - Set the done quantity to 2. - Validate the picking without creating a backorder. - Try to split the validated/done picking. - An expected singleton traceback is raised. Cause of the issue: ========================= Previously, attempting to split a done picking simply returned because there was nothing left to split. After this [PR](https://github.com/odoo/odoo/pull/224952), the split action calls **message_post()** to post a note on the original picking of the generated backorder. However, no backorder is created when splitting a done picking since there is no remaining quantity to split. As a result, message_post() is called on an empty recordset, leading to an expected singleton traceback. With This Commit: ========================= Splitting a done picking has no functional purpose, as there is nothing left to split. In this case, simply return without performing any action. This preserves the previous behaviour and prevents the traceback. Forward-Port-Of: odoo/odoo#274855 Forward-Port-Of: odoo/odoo#274382
This update fixes a flaky test in the HTML editor toolbar, which was sometimes failing because browser events were processed at unpredictable times. It improves reliability in testing without changing the end-user behavior of the editor.
Original PR description
### Description of the issue/feature this PR addresses: - Resolve non-deterministic failures in the 'toolbar should not open between double and triple click' Hoot test. - Because browser-level selectionchange events are dispatched asynchronously in the event loop, asserting on the presence of `.o-we-toolbar` in the DOM leads to timing race conditions. ### Solution: - Resolves the flakiness by introducing a wrapper method `triggerDebouncedUpdateToolbar` in `ToolbarPlugin` and refactoring the test to track method call sequences instead of asserting on DOM elements. This verifies the scheduled debounced updates in a deterministic sequence. task: https://runbot.odoo.com/odoo/error/243145 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274498 Forward-Port-Of: odoo/odoo#273303
Currently, if you have an error in the response, we don't try to get the error message, we just give the type of error. Let us do that. Partial fw-port of https://github.com/odoo/odoo/commit/4bfe16cd45828a864a159b566d7983246e7e03a5 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273754
Original PR description
Currently, if you have an error in the response, we don't try to get the error message, we just give the type of error. Let us do that. Partial fw-port of https://github.com/odoo/odoo/commit/4bfe16cd45828a864a159b566d7983246e7e03a5 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273754
Before this commit, selecting one or more rows in a list view disabled text selection on the whole list, which also prevented users from selecting the totals displayed in the footer. This commit fixes the issue on the list footer, so totals remain selectable even when rows are selected. task:6240238 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272126
Original PR description
Before this commit, selecting one or more rows in a list view disabled text selection on the whole list, which also prevented users from selecting the totals displayed in the footer. This commit fixes the issue on the list footer, so totals remain selectable even when rows are selected. task:6240238 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272126
The following use case has been observed: 0. Customer start a payment from /shop/payment. 1. We received the webhook that notifies that the payment succeeded. 2. The payment post-processing cron start (it gather all the transactions that need to be processed, including the customer new transaction) 3. Meanwhile, the customer is redirected back by the payment provider to Odoo, which then redirect to /payment/status and start the payment post-processing for that specific transaction 4. The
Original PR description
The following use case has been observed: 0. Customer start a payment from /shop/payment. 1. We received the webhook that notifies that the payment succeeded. 2. The payment post-processing cron…
The following use case has been observed: 0. Customer start a payment from /shop/payment. 1. We received the webhook that notifies that the payment succeeded. 2. The payment post-processing cron start (it gather all the transactions that need to be processed, including the customer new transaction) 3. Meanwhile, the customer is redirected back by the payment provider to Odoo, which then redirect to /payment/status and start the payment post-processing for that specific transaction 4. The customer initiated payment processing finishes, he is redirected back to /my/orders/... page. 5. The payment post-processing cron finally start processing the same customer transaction and process it (a second time). In that case, as the transactions to be post-processed backlog was quite high, there is consequent time between the time we gather all the TXs to post-process and actually process the customer transaction. Also we don't end up with a `SerializationError` as the cron do commit after each transaction post-processing. This commit force invalidate individual transaction cache values and recheck if it effectively still need to be post-processed before doing it. opw-6332192 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274725 Forward-Port-Of: odoo/odoo#274010
Set message_type as 'comment' only when creating a new message. Updating content should not change it. Task-6368820 Part of Task-3704380 Forward-Port-Of: odoo/odoo#274988
Original PR description
Set message_type as 'comment' only when creating a new message. Updating content should not change it. Task-6368820 Part of Task-3704380 Forward-Port-Of: odoo/odoo#274988
Remove useless assignation of state from frontend in `_check_pos_order` because its overrided just after in the process. Forward-Port-Of: odoo/odoo#272925 Forward-Port-Of: odoo/odoo#272176
Original PR description
Remove useless assignation of state from frontend in `_check_pos_order` because its overrided just after in the process. Forward-Port-Of: odoo/odoo#272925 Forward-Port-Of: odoo/odoo#272176
Toggle invoice button was making a call in IN localization even when not in a IN country. This was causing an error in runbot 940146. This commit fixes the issue by checking if the country is IN before making the call. In `pos_settle_due` the method signature was not correct. The linked enterprise commit also fix it. Forward-Port-Of: odoo/odoo#275055
Original PR description
Toggle invoice button was making a call in IN localization even when not in a IN country. This was causing an error in runbot 940146. This commit fixes the issue by checking if the country is IN before making the call. In `pos_settle_due` the method signature was not correct. The linked enterprise commit also fix it. Forward-Port-Of: odoo/odoo#275055
In commit [1], the settings search was simplified to address performance issues. The intent was to limit the search scope to the primary visible text: field labels and help text. However, an error was made, and the search inadvertently targeted the `title` attribute (tooltips) instead of the `help` text. This commit corrects the search scope so it properly searches the `help` text as originally intended. [1] https://github.com/odoo/odoo/commit/87212d2123b354c7929db82ab4748a293e401b4b ta
Original PR description
In commit [1], the settings search was simplified to address performance issues. The intent was to limit the search scope to the primary visible text: field labels and help text. However, an error was made, and the search inadvertently targeted the `title` attribute (tooltips) instead of the `help` text. This commit corrects the search scope so it properly searches the `help` text as originally intended. [1] https://github.com/odoo/odoo/commit/87212d2123b354c7929db82ab4748a293e401b4b task-id 6376582
Steps to reproduce: 1. Install website_hr_recruitment and hr_appraisal modules. 2. Remove `Appraisals`'s rights from admin. 3. Create appraisal & add `contactus` link in employee feedback. 3. Go to Website > Site > Pages. 4. Delete the contact us page. > An access error is raised on the employee_feedback field. Employee_feedback has field level access rights so when preparing the list of records depending on a deleted page, the search was performed with sudo, but the records were late
Original PR description
Steps to reproduce: 1. Install website_hr_recruitment and hr_appraisal modules. 2. Remove `Appraisals`'s rights from admin. 3. Create appraisal & add `contactus` link in employee feedback. 3. Go to Website > Site > Pages. 4. Delete the contact us page. > An access error is raised on the employee_feedback field. Employee_feedback has field level access rights so when preparing the list of records depending on a deleted page, the search was performed with sudo, but the records were later accessed without sudo. This could trigger an access error on related fields. Use sudo while preparing the dependency list, as we only search the records and read their names. No sensitive fields are being exposed. task-6267364 Forward-Port-Of: odoo/odoo#273827 Forward-Port-Of: odoo/odoo#269790
### Description: When trying to install the module `l10n_es_edi_verifactu` on a database that already has moves, it is possible to encounter a timeout or a memory error. This is caused by the compute `l10n_es_edi_verifactu_state` and `l10n_es_edi_verifactu_clave_regimen`, both compute linked to the new model `l10n_es_edi_verifactu.document`. ### Reference: opw-6293590 Forward-Port-Of: odoo/odoo#273416 Forward-Port-Of: odoo/odoo#271550
Original PR description
### Description: When trying to install the module `l10n_es_edi_verifactu` on a database that already has moves, it is possible to encounter a timeout or a memory error. This is caused by the compute `l10n_es_edi_verifactu_state` and `l10n_es_edi_verifactu_clave_regimen`, both compute linked to the new model `l10n_es_edi_verifactu.document`. ### Reference: opw-6293590 Forward-Port-Of: odoo/odoo#273416 Forward-Port-Of: odoo/odoo#271550
Steps to reproduce: - - Create a sale order. - Link a project using the Project field. - Confirm the sale order. - Click on the Project smart button. Issue: - The Project smart button is displayed since the sale order has a linked project. However, clicking on it does nothing. Cause: - A sale order without order lines can still have projects linked through the project_id field. The action should not assume that no order lines means there are no projects to display. Solution: -
Original PR description
Steps to reproduce: - - Create a sale order. - Link a project using the Project field. - Confirm the sale order. - Click on the Project smart button. Issue: - The Project smart button is displayed since the sale order has a linked project. However, clicking on it does nothing. Cause: - A sale order without order lines can still have projects linked through the project_id field. The action should not assume that no order lines means there are no projects to display. Solution: - Remove the unnecessary order line check and allow the existing logic to open the linked projects. task-6209658 Forward-Port-Of: odoo/odoo#270752
This commit adds an index to speed up the task name_search in timesheets when project_timesheet_holidays is installed. Forward-Port-Of: odoo/odoo#273925
Original PR description
This commit adds an index to speed up the task name_search in timesheets when project_timesheet_holidays is installed. Forward-Port-Of: odoo/odoo#273925
When changing the quantity of a pos order line the fiscal position set on the order was not used when recomputing the line price and taxes. Steps to reproduce: ------------------- * Create a tax with 15% rate and another with 10% rate * Create a fiscal position that maps the 15% tax to the 10% tax * Setup a PoS to be able to use that fiscal position * Open the PoS, add a product with the 15% tax, set the fiscal position and validate the order * Refund the order in the backend and change
Original PR description
When changing the quantity of a pos order line the fiscal position set on the order was not used when recomputing the line price and taxes. Steps to reproduce: ------------------- * Create a tax with 15% rate and another with 10% rate * Create a fiscal position that maps the 15% tax to the 10% tax * Setup a PoS to be able to use that fiscal position * Open the PoS, add a product with the 15% tax, set the fiscal position and validate the order * Refund the order in the backend and change the quantity of the line from -1 to 0 and back to -1. > Observation: The price is not the same as before Why the fix: ------------ The fiscal position was not applied when recomputing the line's price and taxes. opw-6253311 Forward-Port-Of: odoo/odoo#274930 Forward-Port-Of: odoo/odoo#270135
When Peppol is installed on a database that was already neutralized (ex: a staging database where the feature is enabled after the neutralization happened), the account_peppol.edi.mode parameter is not set: data/neutralize.sql only runs at neutralization time, not when the module is installed afterwards. The demo/ data that also sets this parameter is not loaded on databases without demo data (real production/staging databases). As a result, _get_peppol_edi_mode() falls back to 'prod' and the
Original PR description
When Peppol is installed on a database that was already neutralized (ex: a staging database where the feature is enabled after the neutralization happened), the account_peppol.edi.mode parameter is not set: data/neutralize.sql only runs at neutralization time, not when the module is installed afterwards. The demo/ data that also sets this parameter is not loaded on databases without demo data (real production/staging databases). As a result, _get_peppol_edi_mode() falls back to 'prod' and the neutralized database registers and sends documents against the live Peppol network. Steps to reproduce: - Neutralize a database on which Peppol is not installed yet - Install the account_peppol module - Open the Peppol settings / registration wizard: the mode is Production instead of Demo Force the demo mode in the pre_init_hook when the database is neutralized, mirroring data/neutralize.sql opw-6307710 Forward-Port-Of: odoo/odoo#274700 Forward-Port-Of: odoo/odoo#273019
Stacktrace during Peppol file generation when creating downpayment from POS - activate peppol (and set system parameter to peppol demo) - create a sale order - on the pos, select order, choose downpayment - pay (for example by card) -> error: <img width="461" height="276" alt="image" src="https://github.com/user-attachments/assets/aadc9467-04e5-413a-97ea-8378252a56a0" /> When an invoice line has no description (name=False in Odoo ORM), base_line.get('name', '') returns False because
Original PR description
Stacktrace during Peppol file generation when creating downpayment from POS - activate peppol (and set system parameter to peppol demo) - create a sale order - on the pos, select order, choose…
Stacktrace during Peppol file generation when creating downpayment from POS
- activate peppol (and set system parameter to peppol demo)
- create a sale order
- on the pos, select order, choose downpayment
- pay (for example by card)
-> error:
<img width="461" height="276" alt="image" src="https://github.com/user-attachments/assets/aadc9467-04e5-413a-97ea-8378252a56a0" />
When an invoice line has no description (name=False in Odoo ORM), base_line.get('name', '') returns False because the key exists. Using `or ''` ensures we always get a string before calling .replace().
Reproduces when generating Peppol XML for a POS down-payment invoice with no line description.
Description of the issue/feature this PR addresses:
Current behavior before PR:
stacktrace:
```
2026-07-03 12:19:39,347 46424 ERROR bsr odoo.http: Exception during request handling.
Traceback (most recent call last):
File ".../lib/python3.13/site-packages/odoo/http.py", line 2856, in __call__
response = request._serve_db()
File ".../lib/python3.13/site-packages/odoo/http.py", line 2331, in _serve_db
raise self._update_served_exception(exc)
File ".../lib/python3.13/site-packages/odoo/http.py", line 2329, in _serve_db
return service_model.retrying(serve_func, env=self.env)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/service/model.py", line 188, in retrying
result = func()
File ".../lib/python3.13/site-packages/odoo/http.py", line 2384, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File ".../lib/python3.13/site-packages/odoo/http.py", line 2599, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File ".../lib/python3.13/site-packages/odoo/addons/base/models/ir_http.py", line 353, in _dispatch
result = endpoint(**request.params)
File ".../lib/python3.13/site-packages/odoo/http.py", line 838, in route_wrapper
result = endpoint(self, *args, **params_ok)
File ".../lib/python3.13/site-packages/odoo/addons/web/controllers/dataset.py", line 32, in call_kw
return call_kw(request.env[model], method, args, kwargs)
File ".../lib/python3.13/site-packages/odoo/service/model.py", line 97, in call_kw
result = method(recs, *args, **kwargs)
File ".../lib/python3.13/site-packages/odoo/addons/pos_sale/models/pos_order.py", line 59, in sync_from_ui
data = super().sync_from_ui(orders)
File ".../lib/python3.13/site-packages/odoo/addons/pos_enterprise/models/pos_order.py", line 25, in sync_from_ui
data = super().sync_from_ui(orders)
File ".../lib/python3.13/site-packages/odoo/addons/point_of_sale/models/pos_order.py", line 1271, in sync_from_ui
order_ids.append(self._process_order(order, False))
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/pos_online_payment/models/pos_order.py", line 78, in _process_order
return super()._process_order(order, existing_order)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/point_of_sale/models/pos_order.py", line 151, in _process_order
return pos_order._process_saved_order(draft)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/point_of_sale/models/pos_order.py", line 161, in _process_saved_order
self._generate_pos_order_invoice()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File ".../lib/python3.13/site-packages/odoo/addons/point_of_sale/models/pos_order.py", line 1196, in _generate_pos_order_invoice
invoice.with_context(skip_invoice_sync=True)._generate_and_send()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File ".../lib/python3.13/site-packages/odoo/addons/account/models/account_move.py", line 6770, in _generate_and_send
wizard.action_send_and_print(allow_fallback_pdf=allow_fallback_pdf)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_peppol/wizard/account_move_send_wizard.py", line 78, in action_send_and_print
return super().action_send_and_print(allow_fallback_pdf=allow_fallback_pdf)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account/wizard/account_move_send_wizard.py", line 397, in action_send_and_print
attachments = self._generate_and_send_invoices(
self.move_id,
**self._get_sending_settings(),
allow_fallback_pdf=allow_fallback_pdf,
)
File ".../lib/python3.13/site-packages/odoo/addons/account/models/account_move_send.py", line 833, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account/models/account_move_send.py", line 723, in _generate_invoice_documents
self._hook_invoice_document_before_pdf_report_render(invoice, invoice_data)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_move_send.py", line 132, in _hook_invoice_document_before_pdf_report_render
._export_invoice(invoice)
~~~~~~~~~~~~~~~^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py", line 46, in _export_invoice
document_node = self._get_invoice_node(vals)
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_21.py", line 21, in _get_invoice_node
document_node = super()._get_invoice_node(vals)
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py", line 142, in _get_invoice_node
self._add_invoice_line_nodes(document_node, vals)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_bis3.py", line 240, in _add_invoice_line_nodes
self._ubl_add_invoice_line_nodes(sub_vals)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_ubl.py", line 1716, in _ubl_add_invoice_line_nodes
self._ubl_add_invoice_line_node(sub_vals)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_bis3.py", line 222, in _ubl_add_invoice_line_node
vals['line_node'].update(self._get_invoice_line_node(sub_vals))
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py", line 415, in _get_invoice_line_node
self._add_invoice_line_item_nodes(line_node, vals)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_bis3.py", line 205, in _add_invoice_line_item_nodes
self._ubl_add_line_item_node(sub_vals)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_ubl.py", line 1092, in _ubl_add_line_item_node
self._ubl_add_line_item_name_description_nodes(sub_vals)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File ".../lib/python3.13/site-packages/odoo/addons/account_edi_ubl_cii/models/account_edi_ubl.py", line 929, in _ubl_add_line_item_name_description_nodes
description = line_name.replace(name, '').strip() # Remove the redundant product's name from the description.
^^^^^^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute 'replace'
```
Desired behavior after PR is merged:
PEPPOL file is generated
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#274034SurveyResult binds a click listener on each .filter-add-answer icon when it starts. The response tables are rendered by a separate interaction, SurveyResultPagination, which swaps the tbody through a t-out directive on every page change and on Show All. Those new rows are nodes SurveyResult never bound, so their filter icon does nothing and the page reloads on the unfiltered view. The direct binding comes from https://github.com/odoo/odoo/commit/dfc1c742e35f75f2c386c4ef50d5584537ac1ed4, which r
Original PR description
SurveyResult binds a click listener on each .filter-add-answer icon when it starts. The response tables are rendered by a separate interaction, SurveyResultPagination, which swaps the tbody through a…
SurveyResult binds a click listener on each .filter-add-answer icon when it starts. The response tables are rendered by a separate interaction, SurveyResultPagination, which swaps the tbody through a t-out directive on every page change and on Show All. Those new rows are nodes SurveyResult never bound, so their filter icon does nothing and the page reloads on the unfiltered view. The direct binding comes from https://github.com/odoo/odoo/commit/dfc1c742e35f75f2c386c4ef50d5584537ac1ed4, which replaced the jQuery delegated handlers that used to survive re-renders. https://github.com/odoo/odoo/commit/c2f0f681714fcb936ce058e8dd4f1b1e9fa7448c reattaches them on tab change but not on pagination or Show All, so only the first page works. Bind updateContent on .pagination_wrapper, which holds the page links and the Show All button and stays outside the re-rendered tbody. A click on either bubbles up and rebinds .filter-add-answer on the rows that were just rendered. Steps to reproduce: 1. Install survey 2. Create a survey with a Date question 3. Share it and record more than ten responses so the responses table spans several pages 4. Open the survey results page and click the list icon on the date question to show the User Responses table 5. Move to page 2 and click the filter icon on any row => The page reloads on the unfiltered view and the selected date is not applied Ticket [link](https://www.odoo.com/odoo/project.task/6238514) opw-6238514 Forward-Port-Of: odoo/odoo#268569
Issue: --- PDF quotes with multiple pages might have display issue on total section, cutting it to halves in two pages. Steps: 1- Set `Boxed` layout in document layout. 2- Create a SO with multiple lines and large descriptions and print it. This issue was previously fixed by 344007299c91d990c851ad9ed6f7fb5f8aa7a273 but the fix was reverted because of its effect on purchase document layout: f2dc10adc5576fc85a8c5100362f1a41c1d13054 Here the proposition is to apply the same fix but thi
Original PR description
Issue: --- PDF quotes with multiple pages might have display issue on total section, cutting it to halves in two pages. Steps: 1- Set `Boxed` layout in document layout. 2- Create a SO with multiple lines and large descriptions and print it. This issue was previously fixed by 344007299c91d990c851ad9ed6f7fb5f8aa7a273 but the fix was reverted because of its effect on purchase document layout: f2dc10adc5576fc85a8c5100362f1a41c1d13054 Here the proposition is to apply the same fix but this time precisely target `#total` from sale order document. opw-5934240 Forward-Port-Of: odoo/odoo#274673
Issue: pos_self_order overrode getServerOrders() to add a separate loadServerOrders() call for it's own orders before delegating to super, resulting in up to an additional sequential RPCs on every order fetch. Fix: Extract the base query domain into a new overridable getServerOrdersDomain() method. Each module overrides it to OR in its own domain via Domain.or([super.getServerOrdersDomain(), extraDomain]), so all orders are fetched in a single RPC call instead of three. Task-6284860 D
Original PR description
Issue: pos_self_order overrode getServerOrders() to add a separate loadServerOrders() call for it's own orders before delegating to super, resulting in up to an additional sequential RPCs on every order fetch. Fix: Extract the base query domain into a new overridable getServerOrdersDomain() method. Each module overrides it to OR in its own domain via Domain.or([super.getServerOrdersDomain(), extraDomain]), so all orders are fetched in a single RPC call instead of three. Task-6284860 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#274548 Forward-Port-Of: odoo/odoo#269260
### Description of the issue/feature this PR addresses: International production payments processed via Redsys are failing with error code 9754 (SIS0754). This rejection occurs because the EMV3DS (3D Secure 2.0) payload is sending the billAddrState field with an invalid ISO code format for non-Spanish customers or customers without a state configured. ### Current behavior before PR: The _redsys_prepare_merchant_parameters method hardcodes the billAddrState key into the DS_MERCHANT_EMV3DS di
Original PR description
### Description of the issue/feature this PR addresses: International production payments processed via Redsys are failing with error code 9754 (SIS0754). This rejection occurs because the EMV3DS (3D…
### Description of the issue/feature this PR addresses: International production payments processed via Redsys are failing with error code 9754 (SIS0754). This rejection occurs because the EMV3DS (3D Secure 2.0) payload is sending the billAddrState field with an invalid ISO code format for non-Spanish customers or customers without a state configured. ### Current behavior before PR: The _redsys_prepare_merchant_parameters method hardcodes the billAddrState key into the DS_MERCHANT_EMV3DS dictionary payload. If self.partner_state_id.code is missing or empty, Odoo sends an empty/falsy value. Because Redsys enforces strict EMV3DS format validation, it rejects the entire transaction for having an invalid state format rather than simply ignoring the empty value. ### Desired behavior after PR is merged: The DS_MERCHANT_EMV3DS dictionary is now constructed dynamically. The billAddrState key is only appended to the payload if a valid state code actually exists for the partner. RedSys allows this field to be optional, so omitting the key entirely when unavailable causes Redsys to skip the validation for that specific field, allowing certain international payments to process successfully. opw-6237764 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273214 Forward-Port-Of: odoo/odoo#270899