Daily updates from Odoo
Thursday, July 9, 2026
45 changes · saas-19.2
Resolved issues and error corrections
Fixes an error that could occur when changing quantities on confirmed Field Service sales orders while an automated incoming-message rule is active. The change keeps unnecessary chatter messages suppressed without breaking automation, improving reliability for sales and field service workflows.
Original PR description
Steps to reproduce: ---------------------------------------- 1. Install `industry_fsm_sale` and `base_automation` modules 2. Create a product with: * Type: Service * Create on order: Task * Project:…
Steps to reproduce:
----------------------------------------
1. Install `industry_fsm_sale` and `base_automation` modules
2. Create a product with:
* Type: Service
* Create on order: Task
* Project: Field Service
3. Create an automation rule with:
* Model: Sales order
* Trigger: Incoming message
4. Create and confirm a sale order with this product
5. Add another product to the SO via the catalog view:
* Change the quantity to 2 or more
Observation:
----------------------------------------
Traceback occurs:
```
File '/home/odoo/src/odoo/addons/base_automation/models/base_automation.py', line 871, in _message_post
message_sudo = message.sudo().with_context(active_test=False)
AttributeError: 'bool' object has no attribute 'sudo'
```
Root Cause:
----------------------------------------
* Catalog qty change calls `set_fsm_quantity()` method
* Setting `fsm_quantity` triggers its inverse `_inverse_fsm_quantity()`, which writes the new qty to the SOL, but passes `fsm_no_message_post=True` in context to suppress chatter noise
https://github.com/odoo/enterprise/blob/ac5d670832a5e0db714c0bd056e1406b50bb4c17/industry_fsm_sale/models/product_product.py#L72-L83
* `sale.order.line.write()` detects a qty change on a confirmed order and calls `_update_line_quantity()`, which posts a message on the parent sale order
* FSM's `message_post` override sees the context flag and returns `False`
* When `base_automation` has an `on_message_received` rule on `sale.order`, it wraps `message_post` at registry load time. That wrapper calls `sudo()` on whatever `message_post` returns, Which was `False`
Solution:
----------------------------------------
Return `self.env['mail.message']` (empty recordset) instead of False, it's still falsy, but it's a proper ORM object that `sudo()` can be called on
opw-6276916
Forward-Port-Of: odoo/enterprise#123010
Forward-Port-Of: odoo/enterprise#119542The French Intrastat export warning links now open only the journal entries with missing required Intrastat information. This prevents users from being sent to unrelated entries and makes it faster to correct export issues before filing.
Original PR description
Steps to reproduce: 1. Have a French company with intrastat report module installed 2. Create and validate a bill to another EU country, without filling out at least one of the required intrastat fields 3. Go to the intrastat report, and export it as XML DEBWEB2 4. In the export wizard, click on the internal links on the warning messages Issues: 1. In the Intrastat report in French localization, when there are missing values detected in the export, the Export Wizard shows internal links that lead to every journal entries - instead of showing only the relevant entries. The warning banner on the report uses the action action_invalid_code_moves which has a domain to limit what is shown on the view form. However in the method _fill_value_errors there was no domain. opw-6215339 Forward-Port-Of: odoo/enterprise#117997
Grid views grouped by a selection field now show the user-friendly label in the drill-down list title instead of the internal technical value. This avoids confusing wording for users when opening details from grouped grid cells.
Original PR description
When grouping a grid view by a selection field and clicking on the cell magnifier, the list title showed the technical name (e.g. non_billable) instead of the display name (e.g. "Non Billable"). This commit adds a condition specifically for selection fields, ensuring that their display names are used. task-5980035 Forward-Port-Of: odoo/enterprise#122303 Forward-Port-Of: odoo/enterprise#120894
Opening the restriction fields on appointment slots no longer causes an error. This keeps appointment slot setup usable for staff when assigning user or resource restrictions.
Original PR description
Clicking the "Restrict to User" or "Restrict to Resources" field on a slot crashed with:
invalid input syntax for type integer: "appointment_type_id.staff_user_ids"
The field domain was a quoted string instead of a list, so it was passed through as a literal value. Remove the domain: it never filtered anything and only broke the form.
opw-6349497
Forward-Port-Of: odoo/enterprise#122651This fix prevents Australian payroll payslip calculations from failing when an employee's Income Stream Type is changed after a payslip has already been created. The payslip now refreshes that information before calculation, helping payroll teams complete processing without unexpected errors.
Original PR description
When an employee's Income Stream Type is changed after a payslip has been created, computing the sheet for payslip will raise a traceback. Steps to reproduce the error: - Install…
When an employee's Income Stream Type is changed after a payslip has been created, computing the sheet for payslip will raise a traceback. Steps to reproduce the error: - Install ``l10n_au_hr_payroll_account`` module with demo data - Switch to ``My Australian Company`` company - Create a new payslip for ``Dennis Cactus`` Employee > Save - Go to Employees > Open the ``Dennis Cactus`` employee > In Payroll tab, Income Stream Type: Other specified payments > Save - Go back to payslip > click the compute sheet button Traceback: ```py KeyError: 'OSP' ``` https://github.com/odoo/enterprise/blob/13e64e0cb7f566cbbb46109fe1c218eb7a14eead/l10n_au_hr_payroll/models/hr_payslip.py#L175-L178 The ``l10n_au_income_stream_type`` field on the payslip is a computed field that only depends on ``employee_id``. As a result, changing the employee's Income Stream Type does not trigger a recomputation of the corresponding field on existing payslip. So, when the ``payslip_ytd_totals`` field is computed, it uses the old value of ``l10n_au_income_stream_type`` field at [1], The resulting ``payslip_ytd_totals`` is then used to build the ``totals`` dictionary, and eventually, when the employee's current ``income_stream_type`` is used to access ``totals``, the mismatch key leads to the above traceback. https://github.com/odoo/enterprise/blob/13e64e0cb7f566cbbb46109fe1c218eb7a14eead/l10n_au_hr_payroll_account/models/hr_payslip.py#L75-L88 [1]: https://github.com/odoo/enterprise/blob/13e64e0cb7f566cbbb46109fe1c218eb7a14eead/l10n_au_hr_payroll/models/hr_payslip.py#L269-L272 solution: I added ``l10n_au_income_stream_type`` to ``add_to_compute()`` in ``compute_sheet()``. This ensures that stale values of ``l10n_au_income_stream_type`` on existing payslips are recomputed when the payslip sheet is computed. sentry-7536819310 Forward-Port-Of: odoo/enterprise#123288 Forward-Port-Of: odoo/enterprise#120143
Blank US checks now print the same payment stub lines that already appeared on pre-printed checks. The check layout was also adjusted so the bottom section fits on a single page, reducing printing errors and wasted paper.
Original PR description
See individual commits. task-6359599 Forward-Port-Of: odoo/enterprise#123144
GIFs in Facebook feed comments were previously missing when users opened the comments window. The update now displays a still preview image and lets users open the animated version on Facebook, making comment content easier to review.
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
Vendor bills imported from Chilean electronic invoices now use the correct amount when the original invoice is in a non-peso currency such as UF. This prevents overstated or understated bills caused by mixing peso totals with the foreign currency on import.
Original PR description
**STEP TO REPRODUCE** 1. Create a invoice to a chilian company, using another currency (for example UF, don't forget setup up a currency rate). 2. Confirm. 3. Download the xml in the chatter, and import it as a vendor bill. 4. Notice the imported bill amount are wrong (Pesos amount are used, with the currency being UF). opw-6269662 Forward-Port-Of: odoo/enterprise#123179 Forward-Port-Of: odoo/enterprise#119664
This update restores a missing text message in the expense Stripe integration. It helps ensure users see the intended guidance or notification instead of a deprecated or incomplete message.
Original PR description
Add missing string runbot-941402 Forward-Port-Of: odoo/enterprise#123495
This fixes an internal test setup issue in the Timesheet Grid assistant so tests load data in the correct order. It helps keep future timesheet updates stable without changing how users work with the app.
Original PR description
Before this commit, the component was mounted in the `beforeEach` block before its `onRpc` mocks were registered. This caused the initial data fetch to fail because the mocks were not yet available during initialization. This commit fixes the test by moving the component mount (`doAction`) inside the test block, strictly after the mocks are defined.
Downloading a Knowledge article as a PDF no longer includes unwanted page scrollbars or the open menu used to start the download. This makes exported articles look cleaner and more professional, especially for longer documents or when the browser is zoomed in.
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
Restaurant platform orders are now included in the normal order fetch instead of requiring extra back-to-back calls. This reduces waiting time and server load when point of sale retrieves orders, especially for UrbanPiper integrations.
Original PR description
Issue: pos_urban_piper 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 Forward-Port-Of: odoo/enterprise#123160 Forward-Port-Of: odoo/enterprise#120001
Fixed DHL delivery validation for shipments created under a company different from the main company. Commercial invoices now receive a valid invoice number, preventing DHL rejection errors for international dutiable deliveries.
Original PR description
Issue ----- When validating a delivery in a different company from the main one, the commercial invoice's number field is incorrect, which raises an error on DHL end.…
Issue ----- When validating a delivery in a different company from the main one, the commercial invoice's number field is incorrect, which raises an error on DHL end. `content/exportDeclaration/invoice/number: expected type: String, found: Boolean` Steps to reproduce ----- - Create a Belgian company - Setup DHL - DHL Product D - Express Worldwide - Dutiable Material enabled - Create an amrican customer - Deliver a product to the american customer > Validation Error Cause ----- The field is populated in https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/delivery_dhl_rest/models/dhl_request.py#L204 The problem is that `next_by_code` uses the company found in the env, whereas the sequence's company is the main one, so it is not found when doing https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/odoo/addons/base/models/ir_sequence.py#L287 ----- Ticket: opw-6171886 Forward-Port-Of: odoo/enterprise#123170 Forward-Port-Of: odoo/enterprise#118379
The point of sale invoice toggle now only runs India-specific checks when the business is actually operating in India. This prevents unnecessary errors in other countries and keeps the payment flow stable.
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
Helpdesk closing reminder emails are now only sent for tickets in stages that are actually eligible for automatic closing. This prevents customers or users from receiving misleading warnings about tickets that will not be closed automatically.
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
The update prevents an automated tax return test from failing when PDF generation overlaps with browser activity. This keeps test results reliable without changing how business users validate tax returns.
Original PR description
Validating a return renders the report to a PDF via wkhtmltopdf inside the `action_validate` request. During the render, the HttpCase test cursor is reserved for wkhtmltopdf, so any browser RPC that overlaps the render window is rejected, resulting in ConnectionLostError. Patching the `_run_wkhtmltopdf` so no real rendering runs during the tour. runbot-243444
The Frontdesk app now explicitly includes the component it needs to display scheduling timelines correctly. This prevents installation or loading issues related to planning views, helping teams use front desk scheduling without interruptions.
Original PR description
runbot-237869 Forward-Port-Of: odoo/enterprise#122292
This fix updates two missed internal references after a field was renamed in the POS pricer module. It prevents errors during module installation when demo data is loaded, making setup more reliable.
Original PR description
The field `pricer_product_to_create_or_update` was renamed to `needs_pricer_update` in the following upgrade commit: https://github.com/odoo/upgrade/commit/bda95f88a6e644bb18b5669ef1a23d49a0111f00 However, two instances were missed in `account_tax.py` and `product_supplierinfo.py`. This caused tracebacks during module installation when loading demo data. Task [link](https://www.odoo.com/odoo/project.task/6373263) task-6373263
Employees and managers can now request an appraisal even when the scheduled next appraisal date has already passed. This removes an unnecessary blocking error and helps teams process overdue appraisals without needing special permissions to change employee settings.
Original PR description
# How to reproduce You need to simulate the fact that you are creating an appraisal late so either : A) Directly edit the `next_appraisal_date` in SQL B) Go to Employee App > any Employee > Settings,…
# How to reproduce You need to simulate the fact that you are creating an appraisal late so either : A) Directly edit the `next_appraisal_date` in SQL B) Go to Employee App > any Employee > Settings, set Next Appraisal Date to tomorrow and wait for 2 days Then : - Click on Request Appraisal - Save # The problem An error is shown saying "You cannot set 'Next Appraisal Date' in the past.". You can workaround this by changing the Next Appraisal Date to a date in the future, but the problem is not every user has the right to do this. # Cause `next_appraisal_date` is also defined in hr.appraisal as a relate field of hr.employee : https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/models/hr_appraisal.py#L56-L57 When creating an hr.appraisal, `next_appraisal_date` is present in `vals_list` because it is defined in the view since : https://github.com/odoo/enterprise/commit/58fba3098f33db82dfbccca2db229550402ed3ab https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/views/hr_appraisal_views.xml#L92 This triggers a write on `next_appraisal_date` of hr.employee which triggers a constraint : https://github.com/odoo/enterprise/blob/0226ad15abc8db70f8e379fddec3d83d15749c85/hr_appraisal/models/hr_employee.py#L81-L85 opw-6147865 Forward-Port-Of: odoo/enterprise#114876
Bank reconciliation entries that apply tax models now correctly show the taxable base amount immediately. This prevents tax lines from appearing with a misleading zero base amount until a manual reset is performed, improving accounting accuracy and reporting clarity.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting 2. Go to Journal entries and create a new one 3. Click Toggle Studio button and go to the view to add the tax_base_amount field to the list of…
### Steps to reproduce the issue: 1. Download Accounting 2. Go to Journal entries and create a new one 3. Click Toggle Studio button and go to the view to add the tax_base_amount field to the list of existing fields 4. Add 2 lines (example): 1. account Product Sales with 1000 dollars credit and 15% tax under Tax column 2. account Bank with 1000 dollars debit 5. Go to Dashboard > Bank > Click the 3 dots of one random bank matching line and click on Manage Models 6. Go to bank fees and add the 15% tax 7. Go back to bank reconciliation and create a new one of 2000 dollars with label bank fees (it will associate the tax automatically) 8. Go back to Journal Entries, group by Journal and search for the transaction of 2000 sollars for account Bank 9. Problem: see that the Base Amount for the 15% bank fees lines (251000 Tax Received account) is 0. Clicking on Reset to draft button the base amount column is automatically updated but this should happen automatically ### Cause of the issue: This occurs because the _lines_prepare_tax_line method in account.bank.statement.line fails to map this field in its return dictionary. ### Reason to introduce the fix: Currently, when applying a reconciliation model with taxes the generated tax lines incorrectly record a tax_base_amount of $0.00. Instead, it should be displayed and calculated. opw-6220948 Forward-Port-Of: odoo/enterprise#122139
This update prevents Redsys from rejecting some international payments when a customer has no state set or no valid state code. Odoo now only sends the state information when it is available, which lets those payments go through successfully.
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
When a receipt triggers an expiration warning before a lot record has been created, the message now falls back to the lot number entered by the user. This prevents confusing “False, False” messages and makes the warning clear and usable during receipt validation.
Original PR description
From saas-18.4, the expiration confirmation wizard can be triggered not only from expired lots, but also from stock move lines whose `removal_date` has passed. For incoming receipts, tracked products…
From saas-18.4, the expiration confirmation wizard can be triggered not only from expired lots, but also from stock move lines whose `removal_date` has passed. For incoming receipts, tracked products use the `lot_name` field when the user is entering the lot. The corresponding `lot_id` is only created later once the receipt is validated. As a result, it is possible for the expiration confirmation wizard to be displayed before the lot exists. In this situation, it attempts to display the product and lot information using `lot_id`, which is still empty, causing the message to show "False, False" instead of the actual lot name entered by the user. It should use the move line information as a fallback when no `lot_id` has been created yet so it still displays the correct product and lot name. Steps to reproduce 1. Enable Product Expiry. 2. Create a storable product with: - Tracking: By Lots - Use Expiration Date: enabled - Removal Time > 0 3. Create a receipt for the product. 4. Open Detailed Operations. 5. Enter a new lot number in the Lot/Serial Number field. 6. Ensure the removal date is in the past and validate the receipt. Related Tickets: opw-6303140 Forward-Port-Of: odoo/odoo#273970 Forward-Port-Of: odoo/odoo#273143
When a message is scheduled to be sent later from an email template, all of its attachments are now correctly linked to the scheduled record. This prevents access issues for other users when they open the related document later.
Original PR description
**Problem:** When scheduling a message using an email template with custom attachments, those attachments will not have their `res_model` and `res_id` updated to relate to the scheduled message…
**Problem:** When scheduling a message using an email template with custom attachments, those attachments will not have their `res_model` and `res_id` updated to relate to the scheduled message record. This can lead to access errors. **Cause:** When composing a message using an email template with attachments, those attachments are created with their `res_model` and `res_id` values corresponding to the mail composer record. However, when scheduling a message, only attachments with no `res_id` value (or a value of 0) are updated to correspond to the scheduled message record. https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mail/wizard/mail_compose_message.py#L1198-L1201 https://github.com/odoo/odoo/blob/30ca89b9e0d3c43d019167ec2de816c263f4bb92/addons/mail/models/mail_scheduled_message.py#L86 **Purpose:** Modify the `mail.scheduled.message` override of `create` to not require an attachment have no `res_id` value to be properly updated. **Steps to Reproduce in Runbot:** 1. Add an attachment to an email template. 2. Open a mail composer using that email template, then schedule the message for later. 3. Attempt to view the scheduled message with a different user. More specific example flow: 1. Add an attachment to the Sales: Send Quotation email template. 2. Create a Quotation and send it with the Send by Email button, selecting Send Later instead of Send. 3. Attempt to view the Quotation with a different user. opw-6293587 Forward-Port-Of: odoo/odoo#272261
This change fixes a test that sometimes failed unpredictably when checking toolbar behavior during quick clicks. It makes the test more reliable by verifying the sequence of actions instead of depending on a browser timing detail, reducing false failures in development and continuous testing.
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
When a message is edited, its type now stays the same instead of being changed to a comment. This keeps message records consistent and avoids unexpected behavior when users update content.
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
This change prevents the website editor from crashing when a user opens the Documents tab after selecting an icon. It improves stability in the media replacement dialog, so users can switch media types without losing their work or encountering an error.
Original PR description
### Steps to reproduce: - Open the website editor and insert a snippet. - Inside the snippet, add an image and a document via /media. - Select the image, click Replace, pick an icon. - Click the icon, then click Replace from the sidebar. - In the dialog, click the Documents tab. - Traceback occurs. ### Root cause: - Both icon and document box elements are `<span>` tags. `DocumentSelector` inherits `selectInitialMedia()` from `FileSelector` which only checks the tag name, so it incorrectly returns true for icons. This causes `fetchAttachments` to call `querySelector(a)` on the icon span, which returns null and crashes. ### Solution: - Override `selectInitialMedia()` in `DocumentSelector` to also check for the `o_file_box` class. Add optional chaining on `querySelector(a)` as a safety net. task-6310147 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270548
This change ensures that databases prepared for testing or staging keep using Peppol demo mode even if the Peppol feature is installed later. It avoids accidentally sending documents to the live Peppol network from a neutralized database.
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
When a task is moved from one project to another, follower notification settings are now updated to match the new project. This ensures people keep receiving the updates they expect, such as stage change notifications, instead of missing important task activity.
Original PR description
Steps to reproduce: - 1. Create projects A and B. 2. Add a user as a follower of project B and select specific notification subtypes (e.g., 'Stage Changed'). 3. Create a task in project A and add the same user as a follower(defaulting to 'Discussions'). 4. Move the task from project A to project B. Issue: - The follower's subscription preferences on the task do not reflect their project-level settings after the move. In the example above, the user remains subscribed only to 'Discussions' and misses 'Stage Changed' updates. Cause: - The default auto-subscription logic skips existing followers. When moving a task, this prevents the system from adding the new project's notification preferences to users who were already following the task. Fix: - Override `_message_auto_subscribe` in project.task to the `update` policy when the `project_id` is changed. task-5877507 Forward-Port-Of: odoo/odoo#248224
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a bom for main with component as component and byproduct as byproduct * Create and confirm a mo for main * Set qty_producing to quantity ot produce * click on "Unreserve" (do_unreserve) * click on "Check availability" (action_assign) * Produce All -> the byproducts will not be produced.
Original PR description
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a…
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a bom for main with component as component and byproduct as byproduct * Create and confirm a mo for main * Set qty_producing to quantity ot produce * click on "Unreserve" (do_unreserve) * click on "Check availability" (action_assign) * Produce All -> the byproducts will not be produced. Observation: ------------- When updating the qty_producing value it will also update the quantity of the byproducts moves: https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mrp/models/mrp_production.py#L892-L893 https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mrp/models/mrp_production.py#L1350 https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/stock/models/stock_move.py#L2382 The quantity on the byproducts move has been updated. When clicking on Unreserve it will call do_unreserve, https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/mrp/models/mrp_production.py#L2297-L2298 It will filters the moves that do not need to be unreserved and select the others: https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/stock/models/stock_move.py#L900 and it will unlink all the sml from the moves: https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/stock/models/stock_move.py#L919 Which will set the quantity on the byproduct moves to 0. When Producing all (button_mark_done) since the qty_producing has already been set, it will simply mark the byproduct move has picked. https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/mrp/models/mrp_production.py#L1323-L1324 In our case, this means that the no byproducts will be created since, the quantity was previously set to 0 opw-6296562 Forward-Port-Of: odoo/odoo#273739 Forward-Port-Of: odoo/odoo#272216
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
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
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
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
Guests never receive any bus notification when the websocket is not handled by Odoo itself but by a proxy that forwards subscriptions through `/websocket/peek_notifications` and dispatches the notifications on its own (which is how Odoo.sh serves databases). The peek controller calls `ir.websocket._prepare_subscribe_data()` directly, bypassing `_subscribe()`, the only method decorated with `@add_guest_to_context`. The guest cookie is present on the request but never read, so the returned chan
Original PR description
Guests never receive any bus notification when the websocket is not handled by Odoo itself but by a proxy that forwards subscriptions through `/websocket/peek_notifications` and dispatches the…
Guests never receive any bus notification when the websocket is not handled by Odoo itself but by a proxy that forwards subscriptions through `/websocket/peek_notifications` and dispatches the notifications on its own (which is how Odoo.sh serves databases).
The peek controller calls `ir.websocket._prepare_subscribe_data()` directly, bypassing `_subscribe()`, the only method decorated with `@add_guest_to_context`. The guest cookie is present on the request but never read, so the returned channel list only contains the anonymous channels (broadcast, res.groups) and lacks the guest's personal ones: ("mail.guest", id), ("discuss.channel", id) and presence. The proxy therefore never registers those channels, and every notification targeted at the guest is silently dropped.
Before this commit, discuss calls with a guest are broken: a 2-person call never connects (p2p offers/answers/ICE are delivered over the bus); in a 3+ person call, any guest who joined before the SFU threshold stays stuck in dead p2p (they never receive the `sfu_hot_swap` notification) while a guest joining as 3rd+ participant works, since the join RPC returns the SFU credentials synchronously.
We override `peek_notifications` with `add_guest_to_context` so the route is aware of guests.
opw-5490739
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#274743This PR adapts the code to call printEventBadge method in pos_event_iot to print the corresponding badge See https://github.com/odoo/enterprise/pull/123478
Original PR description
This PR adapts the code to call printEventBadge method in pos_event_iot to print the corresponding badge See https://github.com/odoo/enterprise/pull/123478
Version: --------- - saas-18.4+ Steps to reproduce: ---------------------- 1. Install `stock` and `purchase` module 2. Create a storable and tracking product with a vendor. 3. Create a reordering rule: Route = Buy, Min Qty = 10, Max Qty = 20 and Trigger `manual` 4. Create a receipt for 10 units from the vendor and confirm it.(Mark as todo). 5. Observe the Order button is hidden in reorder rule(expected—incoming qty covers the minimum) 6. Delete the receipt move line. 7. Open reord
Original PR description
Version: --------- - saas-18.4+ Steps to reproduce: ---------------------- 1. Install `stock` and `purchase` module 2. Create a storable and tracking product with a vendor. 3. Create a reordering…
Version:
---------
- saas-18.4+
Steps to reproduce:
----------------------
1. Install `stock` and `purchase` module
2. Create a storable and tracking product with a vendor.
3. Create a reordering rule: Route = Buy, Min Qty = 10, Max Qty = 20
and Trigger `manual`
4. Create a receipt for 10 units from the vendor and confirm it.(Mark as todo).
5. Observe the Order button is hidden in reorder rule(expected—incoming qty covers the minimum)
6. Delete the receipt move line.
7. Open reordering rule and check order button
Issue:
------
After deleting a confirmed incoming move, the Order button on the reordering rule
does not reappear, even though there is no longer any incoming quantity to cover
the minimum threshold.
Cause:
-------
https://github.com/odoo/odoo/blob/adabd8cc47b1c5992f0f92631da73977be8beaca/addons/stock/views/stock_orderpoint_views.xml#L55-L56
The Order button visibility is driven by `qty_to_order > 0` on the orderpoint.
`qty_to_order` itself resolves to `qty_to_order_computed` (a stored field) when no
manual override is set:
https://github.com/odoo/odoo/blob/adabd8cc47b1c5992f0f92631da73977be8beaca/addons/stock/models/stock_orderpoint.py#L317-L319
```
qty_to_order─depends─>qty_to_order_computed (stored)
│
└─ reads qty_forecast (non-stored, computed)
│
└─ depends on product_id.stock_move_ids.
```
`_compute_qty_to_order_computed` checks whether `qty_forecast < product_min_qty`.
If so, it calculates how much to order to reach `product_max_qty`. When a confirmed
incoming move exists, its quantity is included in `qty_forecast`,
https://github.com/odoo/odoo/blob/adabd8cc47b1c5992f0f92631da73977be8beaca/addons/stock/models/stock_orderpoint.py#L347
This return False.
So, `qty_to_order_computed = 0` → button hidden.
To avoid recomputing `qty_to_order_computed` for all orderpoints on every stock
move change severe performance issue — see [Commit](https://github.com/odoo/odoo/commit/6f2d1b26b34129cfbd62d2fe44f306bfe89794b5
),
`qty_forecast` is intentionally excluded from
`@api.depends` on `qty_to_order_computed`. Instead,
`_update_orderpoints()` is called selectively from `create()` and `write()` to
schedule a targeted recompute via `env.add_to_compute()`.
However, `unlink()` never called `_update_orderpoints()`, so deleting a move left
`qty_to_order_computed` stale at 0 — the Order button stayed hidden permanently.
Solution:
---------
- `_update_orderpoints()` now returns the found orderpoints recordset.
- `unlink()` calls `_update_orderpoints()` before deletion to capture the affected
orderpoints (product_id / location data still accessible), then calls
`_compute_qty_to_order_computed()` immediately after `super().unlink()`.
opw-6174454
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#274832
Forward-Port-Of: odoo/odoo#264039Use case -------- A recurring sale order, is automatically invoiced. The transaction is postprocessed and crash with this traceback ``` File "/home/odoo/src/enterprise/saas-19.2/sale_subscription/models/sale_order.py", line 1881, in _handle_automatic_invoices invoice._post() File "/home/odoo/src/custom/private/openerp_enterprise/models/subscription_assignation.py", line 439, in _post posted_moves = super()._post(soft=soft) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/odoo/src/custom/private
Original PR description
Use case -------- A recurring sale order, is automatically invoiced. The transaction is postprocessed and crash with this traceback ``` File…
Use case
--------
A recurring sale order, is automatically invoiced. The transaction is postprocessed and crash with this traceback
```
File "/home/odoo/src/enterprise/saas-19.2/sale_subscription/models/sale_order.py", line 1881, in _handle_automatic_invoices
invoice._post()
File "/home/odoo/src/custom/private/openerp_enterprise/models/subscription_assignation.py", line 439, in _post
posted_moves = super()._post(soft=soft)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/custom/private/openerp_enterprise/models/account.py", line 193, in _post
posted = super()._post(soft)
^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/hr_payroll_expense/models/account_move.py", line 21, in _post
res = super()._post(soft=soft) # Posting will automatically reconcile same-account-same-matching lines
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/l10n_in_reports/models/account_move.py", line 135, in _post
to_post = super()._post(soft=soft)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/account_loans/models/account_move.py", line 20, in _post
posted = super()._post(soft)
^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/sale_subscription/models/account_move.py", line 21, in _post
posted_moves = super()._post(soft=soft)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/account_invoice_extract/models/account_invoice.py", line 235, in _post
posted = super()._post(soft)
^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/account_asset/models/account_move.py", line 130, in _post
posted = super()._post(soft)
^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_it_edi/models/account_move.py", line 360, in _post
return super()._post(soft)
^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_in_edi/models/account_move.py", line 156, in _post
res = super()._post(soft=soft)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/account_peppol_response/models/account_move.py", line 42, in _post
res = super()._post(soft)
^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/sale/models/account_move.py", line 149, in _post
invoice.js_assign_outstanding_line(line.id)
File "/home/odoo/src/enterprise/saas-19.2/account_accountant/models/account_move.py", line 589, in js_assign_outstanding_line
super().js_assign_outstanding_line(line_id)
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_move.py", line 6430, in js_assign_outstanding_line
return lines.reconcile()
^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_move_line.py", line 3324, in reconcile
return self._reconcile_plan([self])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_move_line.py", line 2978, in _reconcile_plan
plan_list, all_amls = self._optimize_reconciliation_plan(reconciliation_plan)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_move_line.py", line 2940, in _optimize_reconciliation_plan
amls._check_amls_exigibility_for_reconciliation(shadowed_aml_values=shadowed_aml_values)
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_move_line.py", line 2832, in _check_amls_exigibility_for_reconciliation
raise UserError(_("You can not reconcile cancelled entries."))
You can not reconcile cancelled entries.
```
Because an old transaction: state = 'reconciled' but is_reconciled is false get attached to the new invoice. The the tx.payment_id.move_id was cancelled by the accounting team, and the invoice was reconcilled directly with the bank statement.
So we end up with a cancelled move that block any further invoice for this subscription.
Solution
--------
According to accounting team, the move_id of the payment is always posted except if there is some manual intervention. We make sure we link only transaction with payment with posted moved
opw-6368231
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-prProblem: when creating a form using the website form builder for models with attributes of type "Reference", these fields also appear in the "Type" builder option for these form fields. The website form builder does not define the template for such fields because the template for such a field cannot be defined generically. Since the template is not defined for reference attributes, a traceback is thrown when a user attempts to add set those attributes as field type. This issue can be reprodu
Original PR description
Problem: when creating a form using the website form builder for models with attributes of type "Reference", these fields also appear in the "Type" builder option for these form fields. The website form builder does not define the template for such fields because the template for such a field cannot be defined generically. Since the template is not defined for reference attributes, a traceback is thrown when a user attempts to add set those attributes as field type. This issue can be reproduced using the following steps with the hr_recruitment addon installed. 1. Add a form on the website 2. Click on it 3. Change 'Form' > 'Action' to 'Apply for a job' 4. Add a field 5. Change its 'Type' to 'UTM reference' Solution: By blocking the model attributes with type "Reference" from being listed under the website form builder field "Type" list, the traceback error can be prevented. task-6317084
When printing the sale details report from the POS ("Print Report"), no date or time appeared on the ticket. During the receipt refactor to shared backend templates, the sale details template and its frontend data builder stopped rendering the print date that previous versions displayed at the bottom of the report. This commit adds the current date and time to the sale details `extra_data` and renders it after the totals, restoring the previous behavior. opw-6348476 --- I confirm I
Original PR description
When printing the sale details report from the POS ("Print Report"), no date or time appeared on the ticket.
During the receipt refactor to shared backend templates, the sale details template and its frontend data builder stopped rendering the print date that previous versions displayed at the bottom of the report.
This commit adds the current date and time to the sale details `extra_data` and renders it after the totals, restoring the previous behavior.
opw-6348476
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prSurveyResult 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
There is a problem with version dates overlapping in the test tour. Delay was added to wait for the next month to load. task-6365181 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#275101 Forward-Port-Of: odoo/odoo#274391
Original PR description
There is a problem with version dates overlapping in the test tour. Delay was added to wait for the next month to load. task-6365181 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#275101 Forward-Port-Of: odoo/odoo#274391
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#274034A recent update caused images within the website builder to fail to load, resulting in slow updates and a broken user experience. This fix addresses a problem where the system incorrectly handles image sources, specifically when an image element doesn't match expected types. The update resolves this by preventing a delayed 404 error.
Original PR description
Commit [1] introduced a `headResponseCache` for images' src, later used in commit [2], which introduced `getFetchedMimetype`. While the former guards against an empty/undefined src, it is not the…
Commit [1] introduced a `headResponseCache` for images' src, later used in commit [2], which introduced `getFetchedMimetype`. While the former guards against an empty/undefined src, it is not the case of the latter. `headResponseCache.read`, which runs a `fetch`, is called within a try/catch, but it is still awaited: with an undefined src, it returns a 404 after stalling the thread for at least 1s. The bug can be seen from the website builder: - Drop a text/image snippet - Open your dev tools on the "network" tab - Click on the image => a failed fetch (404) appears and blocks the builder from being updated quickly. It happens because the element (in this case the `section` of the snippet) is neither an `img`, nor an element with a parallax, nor an element with a background-image, and `getImageSrc` returns an undefined src. [1]: https://github.com/odoo/odoo/commit/bf377f3d1c58aaeb39624700b3e4754d7a6d384b [2]: https://github.com/odoo/odoo/commit/b96a0769eeecd2e6ec14cc7a73105f8dfdb8842e task-6247171 Forward-Port-Of: odoo/odoo#274641