Monday, September 29, 2025
54 changes · saas-18.4
Resolved issues and error corrections
This fixes test coverage for product barcode lookup so product weight is validated when available and the correct product variant permissions are used. It helps ensure barcode lookup product data is handled reliably without changing day-to-day user workflows.
Original PR description
Before this commit: ------------------------- - The weight and volume fields were not present in the main product form, so we can't set them. - The variant rights were not passed correctly for the first basic test. After this commit: ----------------------- - We have updated the test and checked that weight is correctly set when present in the view. - Now we have passed the correct variant right for the test. Runbot error: https://runbot.odoo.com/odoo/runbot.build.error/231155 Forward-Port-Of: odoo/enterprise#95590 Forward-Port-Of: odoo/enterprise#93075
This fix prevents Field Service tasks from failing when a previously created worksheet template remains after the app is uninstalled and reinstalled. User-created worksheet templates are now cleaned up during uninstall, avoiding broken template references and improving reliability for teams using worksheets.
Original PR description
When user uninstalls and reinstalls `industry_fsm` the user created template is not removed causing `model_id` for the worksheet template turning `False` and raising a key error when indexing via `model_id`. **Replication steps:** * Install `industry_fsm` * Field Service>Configuration>Settings>Enable Worksheet templates * Configuration>Templates>Create New Template * Uninstall and reinstall `Field Service` * Field Service>New Task>Set worksheet template to the one you created `KeyError: False` **Solution:** * Unlink user created worksheet template on uninstallation of the application. **Sentry-6615576986** Forward-Port-Of: odoo/enterprise#86084
This fix stops cashiers from repeatedly pressing Validate while an online payment order is still syncing on slow networks. It prevents payment validation errors and makes point-of-sale checkout more reliable when connectivity is poor.
Original PR description
Currently, an error occurs when validating an online payment if the network is slow. **Steps to Reproduce:** 1) Install POS (with demo data) and the Demo Payment module. 2) Go to Payment Methods and…
Currently, an error occurs when validating an online payment if the network is slow.
**Steps to Reproduce:**
1) Install POS (with demo data) and the Demo Payment module.
2) Go to Payment Methods and create a new online payment method for any shop (e.g., a clothing shop). Set the Payment Provider to `Demo`.
3) Open a POS session for the clothing shop, select any product, and proceed to payment.
4) Open Inspect → Network tab, create a custom slow network profile(e.g., `set both download and upload speed to 1 KB/s`), and switch to that network.
5) Select the online payment method you just created and continuously click on Validate.
Error:
ValueError: Expected singleton: pos.order('p', 'o', 's', '.', 'o', 'r', 'd', 'e', 'r', '_', '4')
**Root Cause:**
When an online payment is validated, the `_isOrderValid` and `addNewPaymentLine` methods are called.
- With a slow network, the order ID is still temporary(e.g., e74a3369-7dcd-4234-b35e-04daa149ffe6) as the order is not synced completely, when the code at [1] is executed.
- Due to multiple clicks, `_isOrderValid` forces a call to `update_online_payments_data_with_server` at [2] before order is synced.
- This eventually passes the temporary ID to `get_and_set_online_payments_data` at [3], causing the issue.
**Fix:**
Prevent multiple clicks on Validate until the order is successfully synced.
[1]- https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/pos_online_payment/static/src/overrides/pos_overrides/components/payment_screen/payment_screen.js#L11-L17
[2]- https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/pos_online_payment/static/src/overrides/pos_overrides/components/payment_screen/payment_screen.js#L87
[3]- https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/pos_online_payment/static/src/overrides/pos_overrides/models/pos_store.js#L18-L26
**sentry-6849786792**
Forward-Port-Of: odoo/odoo#227967
Forward-Port-Of: odoo/odoo#225371This fix prevents a self-ordering test from trying to cancel orders that are already finalized, such as paid demo orders. By limiting cancellations to draft orders, the test runs more reliably and avoids false failures in validation environments.
Original PR description
Before this commit: = - Previously, `test_self_order_mobile` set all orders to cancel, causing errors with finalized orders (e.g., paid orders from demo data). After this commit: = - Only draft orders are cancelled, preventing errors and ensuring correct test behavior. Runboat Error: 224197 Forward-Port-Of: odoo/odoo#214935
Dark mode styling was adjusted so key icons and text remain easy to read in Point of Sale and appointment views. This improves usability for staff working with dark mode by preventing low-contrast or hard-to-see interface elements.
Original PR description
In this commit: ------------------- - Added a dark mode color for the star icon. - Changed the text color to white in light mode, which is reflected as black in dark mode. This fixes the issue of the text not being properly visible in dark mode. task:4943078 Forward-Port-Of: odoo/enterprise#93993
UAE invoice printouts have been corrected so the amount column is no longer shown twice when taxes are included. This makes Proforma and Tax invoice reports clearer and avoids confusion for customers and accounting teams.
Original PR description
**Step to reproduce:** - install account module with localization "UAE" - go to Settings > Tax Included - create a invoice (make sure a tax is applied) - print any invoice (Proforma or Tax)…
**Step to reproduce:**
- install account module with localization "UAE"
- go to Settings > Tax Included
- create a invoice (make sure a tax is applied)
- print any invoice (Proforma or Tax)
**Observation:**
- the amount is being displayed twice in the Amount column.
**Cause:**
- A change was introduced in 18.0 to add additional column right after Amount
column, [1] in l10n_ae module
- Another commit [2] in saas-18.3 introduces same column in main account module
- hence we have two columns printing same information
**Fix:**
- Removed and fixed a faulty xpath from view, as after commit [2]
base layout provides same logic
[1] https://github.com/odoo/odoo/commit/fe68fa30b18f90411043fc6e2314fd376ddaed0c
[2] https://github.com/odoo/odoo/commit/1bf232c22f430d282aaadd858c5e61fed12f4da6
**Before:**
<img width="774" height="146" alt="image" src="https://github.com/user-attachments/assets/a9eb6af2-81b3-4989-bf6e-6676eafe10f8" />
**After:**
<img width="813" height="143" alt="image" src="https://github.com/user-attachments/assets/fb019516-de7d-4dd3-b7dd-3fd14322b031" />
opw-4976410
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#223382Support Document Credit Notes in Colombian electronic invoicing now use the required internal reference identification format, avoiding DIAN rejection errors. This helps businesses submit these credit notes successfully even when product barcodes or UNSPSC codes are configured.
Original PR description
Before this PR:
- Support Document Credit Notes sent barcode (scheme 010) when available, causing DIAN `NSAZ13` error and document rejection.
After this PR:
- Although a product has all of these 3 fields configured (barcode, UNSPSC, internal reference), still, for a Support Document Credit Note, the `cac:StandardItemIdentification` is always sent with the Internal Reference information ('999', 'Estándar de adopción del contribuyente').
- If internal reference is not configured, then barcode or UNSPSC code is sent with scheme ('999', 'Estándar de adopción del contribuyente').
task-4796034
Forward-Port-Of: odoo/enterprise#94140This fix prevents manufacturing planning from failing when an operation or work order has an extremely small duration value. It ensures schedules can still be calculated reliably instead of triggering an error during availability checks.
Original PR description
Operation & Workorder duration is a float with 2 decimal digits to be expressed in minutes, meaning minimal duration is 1sec. However one can encounter numbers like 0.001, 0.00001, ... This can lead to : AttributeError: 'NoneType' object has no attribute 'astimezone' in function _get_first_available_slot task: 5090338 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227253
Employees and contract templates using a working schedule now require Working Hours before saving. This prevents errors in employee forms and version lists, helping HR teams keep work entry data complete and reliable.
Original PR description
#### Steps to Reproduce 1. Go to Employees. 2. Select an employee with Work Entry Source = "Working Schedule". 3. Clear the "Working Hours" field. 4. Try to save. #### Issues Fixed - Traceback in employee version list view (`hr.version`) when "Working Hours" is empty for calendar-based employees. - Traceback in employee form view when saving without a working schedule for a calendar-based employee. - Resource Calendar (`resource_calendar_id`) is now required conditionally in: * Employee form view * Contract template form view * Version list view #### Fix Made `resource_calendar_id` required conditionally in the inherited `hr.employee`, `hr_contract_template` and `hr.version` views and added a placeholder. task-5068798
Invoice and report lines now show both the product name and the added description instead of replacing the product name with the description. This helps customers and staff identify billed items more clearly on printed documents.
Original PR description
Step to reproduce: - install account - create a invoice with any product - add description - print any report Observation: - We see that only description is printed, not the name of product in…
Step to reproduce: - install account - create a invoice with any product - add description - print any report Observation: - We see that only description is printed, not the name of product in description column of report Expected: - The name and description, both should be printed Cause: - the `ProductNameAndDescriptionField` component is introduced in [1] sets label as only description or product name, instead of including it both if they are available https://github.com/odoo/odoo/blob/f74cdf84ffbaccea2fbf03bfb17a9e7bfcaae524/addons/product/static/src/product_name_and_description/product_name_and_description.js#L131-L136 Fix: - we fix the `updateLabel` method for `ProductNameAndDescriptionField` to get the expected outcome i.e `productname+\n+description` Before: <img width="297" height="175" alt="image" src="https://github.com/user-attachments/assets/803b53ce-c031-4192-874c-11ebfd8c7e9b" /> After: <img width="281" height="184" alt="image" src="https://github.com/user-attachments/assets/0dce4f67-94bf-42f2-bf09-c03a07c800d0" /> [1]: https://github.com/odoo/odoo/commit/7e553d25890d1e236123f0fa7e11ce86f59448ab opw-5063048 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents email signature formatting, such as resized images, from being damaged when messages are prepared for Outlook compatibility. Users should see more consistent email appearance between chatter messages and the full email composer.
Original PR description
Problem: `_hideForOutlook` breaks the last style when appending `mso-hide: all;` if the style string does not end with `;`. Example: `width: 100%` → `width: 100% mso-hide: all;` Solution: Ensure the new attribute is appended correctly at the end of the styles, regardless of whether the last style ends with `;`. Note: The problem might be only observed on `18.4` because the composer doesn't use the user signature before `18.4`. Steps to reproduce in 18.4: 1. Open "My Profile". 2. Add an image to "email signature" with reduced scaling (25%, 50%). 3. Open any record with chatter (task, SO, invoice, etc.). 4. Type a message in chatter and click "Send". 5. Click "Open Full Compositor" and send a message from the email compositor. 6. Open the runbot's MailHog and observe the differences between the two emails. opw-5046573 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224985
This fixes an issue where an online order could switch to the wrong pricelist after a shopper created an account without an address. The website now keeps using the shopper's detected country when recalculating prices, helping ensure country-specific pricing remains accurate.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have GeoIP enabled/mocked; 2. have at least 2 pricelists available in eCommerce; 3. have all pricelists restricted to a certain country group; 4. have the 1st…
Versions -------- - 17.0+ Steps ----- 1. Have GeoIP enabled/mocked; 2. have at least 2 pricelists available in eCommerce; 3. have all pricelists restricted to a certain country group; 4. have the 1st pricelist be incompatible w/ the current GeoIP location; 5. open a cart as a public user; 6. check pricelist in back-end (should be correct); 7. go to "Sign In" & create a new portal account without address; 8. check pricelist in back-end (should still be correct); 9. go back to cart with portal account; 10. check pricelist in back-end. Issue ----- The first pricelist is assigned to the order, which shouldn't be compatibly with the partner's current GeoIP location. Cause ----- The pricelist is recomputed on changing the `partner_id` on a sale order. Commit 6504c0624b990 added a check on the `country_code` context value when retrieving the `property_product_pricelist` for a partner. This context value is currently not getting added during `_compute_pricelist_id`. Because all pricelists are restricted to a country group, when the pricelist gets recomputed on `partner_id` change, there's no location-independent pricelist to fall back on, which is why the first pricelist is used regardless of country restrictions. Solution -------- Add a `_compute_pricelist_id` override which adds the current GeoIP country code to the context when computing the field for website orders. opw-5000198 Forward-Port-Of: odoo/odoo#228909 Forward-Port-Of: odoo/odoo#225582
The AI field picker now prevents users from selecting the same field more than once and clearly marks fields that are already selected. Long field paths also wrap correctly, making them easier to remove and reducing user frustration when configuring AI prompts.
Original PR description
before this commit: When you press Enter in the field picker, it will always pick the same field again, even if it is not visible. After this commit: A field can only be selected once, and it stays visible in the list. Added a visual check to show that the field is already selected. Forward-Port-Of: odoo/enterprise#93890
Importing certain electronic invoice files could fail when a quantity field was set to zero. This fix prevents that error so affected UBL/CII invoices can be imported more reliably in Accounting.
Original PR description
**Steps to reproduce:** - Install Accounting - Go to "Accounting / Customers / Invoices" - Import a UBL file having a value of 0 for a `<cbc:BaseQuantity>` element **Issue:** The import fails due to a division by 0 at: `price_unit = (net_price_unit + rebate) / basis_qty` **Cause:** "basis_qty" is retrieved as followed: `basis_qty = float(self._find_value(xpath_dict['basis_qty'], tree) or 1)` If the element is not defined, it will fall back on 1. But if the element exists with a value of 0, the "_find_value" method will retrieve the string "0" which is not False and will not fall back on 1. Then it will become `0.0` once converted to float. opw-5062985 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227446
Project users can no longer create new task stages from the task list when they do not have the required permissions. This keeps project workflows controlled by authorized managers and prevents unintended changes to task stage setup.
Original PR description
Steps to reproduce: - Go to a project - Open the task list view - Select a task - In the `Stage` field, attempt to create a new stage Issue: - Project users were able to create new task stages from…
Steps to reproduce: - Go to a project - Open the task list view - Select a task - In the `Stage` field, attempt to create a new stage Issue: - Project users were able to create new task stages from the task list view, despite not having the required permissions. Cause: - The `_default_user_id` method assigns the current user as the owner `user_id` of a new stage only when `default_project_id` is not present in the context. As a result, the method returned the current user’s ID, unintentionally making them the owner of the stage. This allowed project users to bypass the intended access rules and create new stages. Solution: - Use the `no_create` option for users outside the project manager group to prevent them from creating new stages. - Updated the `stage_id` field in the task list view to explicitly include `default_project_id` in the context, ensuring proper access control of that stage. task-4628666 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228766 Forward-Port-Of: odoo/odoo#206407
Rental orders can now be confirmed even if a planned resource is unavailable, as long as rental-to-shift synchronization is turned off. This prevents unnecessary blocking in the portal and rental app for businesses that do not use shift synchronization.
Original PR description
Step to reproduce: - Set up a role with a resource not available this week - Not activate the option to sync Rental order - Shift - Set up a rental-service product, with an auto-plan for this role Issue: - Rental orders could not be confirmed from the portal or the rental app if the required resource was unavailable, even when the `sync_shift_rental` option was not disabled. Cause: - The logic in `_planning_slot_vals_list_per_sol` treated all unavailable resources as problematic, without checking whether the shift synchronization was enabled (`sync_shift_rental`), resulting in unnecessary blocking of the order confirmation. Solution: - Added a condition to check if `sync_shift_rental` is enabled before marking a service as problematic. This allows rental orders to be confirmed when shift sync is disabled. task-5072920
This fixes a rounding mismatch in Mexican electronic invoice validation, where Odoo calculated totals with more precision than the XML validation expected. The change helps prevent valid invoices from being rejected due to tiny decimal differences.
Original PR description
The validation in the XML are made based on values rounded to 6 digits. However in Odoo, we do the computation without any rounding. 352.2413793103448 + 876.7435344827586 + 162.92327586206898 + 198.73706896551727 + 526.0383620689655 + 17.241379310344826 = 2133.925 ~= 2133.93 352.241379 + 876.743534 + 162.923276 + 198.737069 + 526.038362 + 17.241379 = 2133.924999 ~= 2133.92 != 2133.93 opw-5096249 Forward-Port-Of: odoo/enterprise#95413
Payment terminal messages printed at the bottom of POS receipts now use the correct text size. This makes receipt details easier for customers and staff to read while keeping the on-screen receipt display consistent.
Original PR description
When you pay with a payment terminal, it can produce some text which gets appended to the bottom of the POS receipt. Before this commit, this text appears too small to be legible when printed on a…
When you pay with a payment terminal, it can produce some text which gets appended to the bottom of the POS receipt. Before this commit, this text appears too small to be legible when printed on a receipt printer. This is because the font size styling was in the wrong place, and in the UI it fell back to bootstrap's CSS which makes it fairly large, but html2canvas renders it very small. After this commit, the problem is fixed by moving the font size styling to the correct place to apply to the text. In the UI, the text is actually slightly smaller than before, but when printed it is bigger and consistent with the UI. Before/After (UI): <img width="346" height="325" alt="image" src="https://github.com/user-attachments/assets/0a9dceb3-e224-473f-b02f-ff94b81b0a8d" /> <img width="349" height="319" alt="image" src="https://github.com/user-attachments/assets/b096172a-4a98-4249-a5d4-00c8a46ab4d0" /> Before/After (Receipt): <img width="513" height="503" alt="image" src="https://github.com/user-attachments/assets/e1d6ba27-1ff6-4853-b617-1c010857f1eb" /> <img width="516" height="528" alt="image" src="https://github.com/user-attachments/assets/82cb2431-707f-40c7-a9a5-f439d3934e16" /> task-5116506 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228775
Invoice Analysis now calculates product quantities, average prices, margins, and inventory values correctly when invoices include packaged products. This helps businesses rely on accurate reporting for sales performance, profitability, and stock valuation after the unit-of-measure packaging changes.
Original PR description
#### Issue: Quantity, average price, margin and inventory value are wrong in Invoice analysis for invoice lines using packagings. #### Step to reproduce: - Choose a product - Make sure it has a cost,…
#### Issue: Quantity, average price, margin and inventory value are wrong in Invoice analysis for invoice lines using packagings. #### Step to reproduce: - Choose a product - Make sure it has a cost, and it differs from sales price - In the sales sheet, add a packaging - Create a sale order - Add the product using the package - Confirm - Go to delivery, validate - Back to sale order create an invoice and confirm it - Go to "Invoice Analysis" - Go to Pivot View - In "Measures" select: - Average Price, - Inventory Value, - Margin, - Product Quantity - In "Total" select: - Product #### Current behavior: - Those fields display wrong values as they were miscalculated: - Average Price line_balance / number_of_packages * number_of_unit_in_package - Inventory Values account_currency_table.rate * number_of_packages / number_of_unit_in_package - Margin margin_on_one_unit * number_of_packages / number_of_unit_in_package - Product Quantity number_of_packages / number_of_unit_in_package #### Expected behavior: - These fields should be right: - Average Price line_balance / number_of_packages / number_of_unit_in_package - Inventory Values account_currency_table.rate * number_of_packages * number_of_unit_in_package - Margin margin_on_one_unit * number_of_packages * number_of_unit_in_package - Product Quantity number_of_packages * number_of_unit_in_package #### Cause of the issue: - As per the refactor of the UoM and packaging, the uom factor field is now the mathematical inverse of the previous uom factor field. This model wasn't updated and used wrong formulas. opw-5031495 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227489
Point of Sale kitchen and preparation tickets now handle order notes consistently across multiple printers. This prevents printing failures caused by different note formats, helping restaurant staff receive complete tickets without interruption.
Original PR description
Normalize getStrNotes() to handle multiple note formats (JSON array string, array, plain string) and avoid crashes when printing preparation tickets to multiple printers. Steps to reproduce:…
Normalize getStrNotes() to handle multiple note formats (JSON array string, array, plain string) and avoid crashes when printing preparation tickets to multiple printers.
Steps to reproduce:
-------------------
* Configure two preparation printers for a pos_restaurant with food categorie.
* Create an order with a note in that restaurant.
* Send the order to the kitchen.
> Observation:
The second printer fails to print the ticket with an (uncaught) JSON parse error (Unexpected token), while the first prints correctly.
Why the fix:
------------
`getStrNotes()` assumed notes were always JSON strings like [{"text":"...","colorIndex":0}]. In practice, notes can be plain strings or already-parsed arrays depending on the update path and last printed changes.
The function now:
- returns joined texts for arrays,
- tries to parse JSON strings and joins texts if it’s an array,
- falls back to the raw string if parsing fails. This makes note rendering stable across printers and prevents the error, ensuring tickets are printed consistently.
opw-5029870
Forward-Port-Of: odoo/odoo#227430The Time Off calendar now shows the selected employee's working schedule instead of the schedule of the person viewing it. This prevents incorrect day-off visibility when managers or HR users review employees with different work patterns.
Original PR description
Steps to reproduce: - In the Employee app, select an employee with a different working schedule than yours - Click on the "Time Off" smartbutton - Switch from Kanban to Calendar view - The displayed working schedule is yours and not the employee's (easier to see if you and the employee have different days off) Reason: The employee_id field in the context used by the Python method was null instead of an ID, which caused the Python method to default to not use the employee's working schedule but the working schedule of the user viewing it. How it was fixed: By using a different field already present in the context, the employee's ID is correctly retrieved and used to display the calendar. Task ID: 4987732 Forward-Port-Of: odoo/odoo#225839
This fixes an issue where reinstalling the Danish Nemhandel module could leave it broken. Businesses using Danish electronic invoicing can reinstall or recover the module without disrupting its setup.
Original PR description
**Description of the issue/feature this PR addresses:** Reinstalling the module breaks it. 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#228747
This fix makes an automated website test wait more reliably when the test environment is running slowly. It reduces false test failures, helping keep development and release validation smoother without changing user-facing website behavior.
Original PR description
__Current behavior before commit:__ The timeout in `waitForReposition` is sometimes reached if runbot is on heavy load making the test fail. __Description of the fix:__ Remove `waitForReposition` and use `waitUntil` instead. This should wait more time if runbot is on heavy load. The timeout has been increased for security. Runbot error: https://runbot.odoo.com/odoo/runbot.build.error/232802
The barcode kanban view now only displays existing inventory quantities instead of allowing new ones to be created by mistake. This helps avoid inaccurate stock records when users scan or type product barcodes and switch to the kanban view.
Original PR description
Steps to reproduce: - Scan or type product barcode - Navigate to Kanban View Problem: - New `stock.quants` are not supposed to be created from `stock.quant.kanban.barcode`, its only to supposed to show existing ones. Forward-Port-Of: odoo/enterprise#95487 Forward-Port-Of: odoo/enterprise#94802
The website builder now opens the edit dialog for the specific submenu a user selected, instead of defaulting to the top-level menu. This prevents confusion and helps website editors update event or nested navigation menus more accurately.
Original PR description
With the initial [website builder refactor], when user wanted to edit sub-menu with "Edit Menu", it opened the dialog to edit the top-level menu. This commit fixes that behavior by looking up the id of the containing menu (if any) Steps to reproduce: - On `/event/<some-event>`, open website builder - Click on a link in the menu of the event (not the top menu) - Click on "Edit Menu" button in the link popover - Bug: the edit menu dialog opens for the top level menu [website builder refactor]: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-4367641
Website editors can now use the "On Hover" animation option on images even after applying a shape. The option is only hidden when the chosen shape already includes its own animation, preventing conflicts while preserving more design flexibility.
Original PR description
Applying a shape to an image unintentionally disabled the "On Hover" animation option. This commit restores the option with proper checks, ensuring it remains disabled only when the applied shape includes an animation. The related code was also refactored slightly for improved readability. Steps to reproduce: 1. Enter edit mode in Website. 2. Add an image and apply a shape. 3. Notice that the "On Hover" animation option is incorrectly hidden.
Turkish Nilvera e-invoice imports now save progress after each document is processed. This reduces the chance of losing all imported documents if a timeout or error occurs during larger imports.
Original PR description
Following bcab79c0ba9b550726164d80a22b50e689a2789c we are no longer committing changes in `_l10n_tr_nilvera_get_documents` as we loop through documents. The idea behind having that commit inside the loop was to avoid having to rollback all changes if we timeout or an error occurs. This is especially important when importing the current maximum amount of documents (30). This commit restores that behavior. No Task ID. Forward-Port-Of: odoo/odoo#228616
The rating form now hides placeholder words like “by” and “on” when there is no related comment or publisher information to show. This removes confusing leftover text and makes rating records easier for users to read.
Original PR description
Steps to Reproduce: 1. Navigate to a rating record form view 2. View ratings without publisher comments 3. Notice confusing 'by on' text fragments appearing Current Behavior: - 'by on' text shows even when there's no comment or publisher information - Text fragments remain visible after comments are removed Expected Behavior: - 'by' and 'on' text should only appear when there's actual content to display - Proper conditional visibility based on comment presence Changes Made: - Added conditional visibility to rating form view text elements - Improved XML structure for better maintainability - Fixed persistent text display issues when comments are removed --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225300
This fixes an automated website menu test that could fail in smaller single-app test builds because the menu did not contain enough items. The change helps keep website test results reliable without affecting end users.
Original PR description
Following this [commit], this tour would fail whenever it is run in single-app test builds. This happened because there were not enough items in the nav for the tour to function properly. Also, removed the "@odoo/hoot-dom" dependency. Build error-231699 [commit]: https://github.com/odoo/odoo/commit/7279c92fcb999f621fd9725c2339247c620ed378
This fix replaces a technical crash with a clearer, user-friendly message when users or customizations try to search unsupported non-stored many-to-many relationship fields. It helps administrators and developers understand the issue faster without exposing confusing internal errors.
Original PR description
When searching non-stored many2many fields, fail with a user-friendly message.
`self.env['account.payment'].search([('reconciled_invoice_ids', '=', 1)])` today results in an AttributeError when trying to get the SQL for the bridge table name.
task-5061329
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe event registration email template now keeps QR codes at the correct size after template edits or previews. This prevents distorted QR codes, helping attendees reliably scan their registration details.
Original PR description
### Steps to reproduce: 1. Set up an event registration with atleast 1 attendee. 2. Go to email templates and search for "Event: Registration Confirmation". (or any with QR code in it) 3. Check the preview of the email template. 4. Edit any text inside the template and check the Preview again. (QR code stop taking the proper height) ### Issue: During the rendering of the email template, the QR code image html is changing provoking the QR to not have the proper aspect ratio and look stretched. ### Fix: We can make sure we're always taking the 100% height of the container by adding a style attribute to the image tag, thus not losing the aspect ratio of the QR code. opw-4976893 Forward-Port-Of: odoo/odoo#223774
This fixes a restaurant point of sale issue where newly added items could appear saved but not be fully synced before being sent to the kitchen printer or preparation display. Staff should no longer encounter the "Order Outdated" error in this workflow, reducing ordering disruptions and inconsistencies.
Original PR description
Before this commit, if an order had no changes and no preparation display was active, adding items to the order in the restaurant PoS and then returning to the tables would sync the order to the server and mark it as not dirty. As a result, reopening the order and clicking the order button to send it to the preparation display or printer would not sync the updated changes. This caused inconsistencies and errors. Steps to reproduce: 1. Open a table, place an order, and send it to the kitchen printer 2. Add more products but instead of placing the order, go back 3. Re-enter the table, place the order, and send it 4. When placing another order, the error "Order Outdated" appears This commit fixes the syncing logic to ensure that last changes are properly synced, avoiding the "Order Outdated" error. opw-5097566 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228680 Forward-Port-Of: odoo/odoo#227824
The Australian Taxable Payments Annual Report now calculates gross paid amounts without incorrectly including customer payments. This helps businesses report supplier taxable payments more accurately and avoid overstating TPAR figures.
Original PR description
Customer payment shoudn't be included in the TPAR report Steps: - Unarchive 10% TPAR tax - Make a bill for a partner X, set 10% TPAR tax on the invoice line and confirm - Create and confirm a customer payment for partner X - Go to 'Taxable Payments Annual Reports (TPAR)' -> The column 'Gross Paid' includes the customer payment Before this commit, we took all line from bank or cash journal to calculate the gross paid value. With this commit, we also restrict the lines to include only the one with 'asset_current' or 'liablility_current' account type. Ticket [link](https://www.odoo.com/odoo/project/967/tasks/5045457) opw-5045457 Forward-Port-Of: odoo/enterprise#95592 Forward-Port-Of: odoo/enterprise#95029
The website SEO dialog now excludes dynamic template images that users cannot edit. This prevents broken image warnings from appearing on pages such as appointments and courses, making SEO optimization guidance clearer and more useful.
Original PR description
**Issue:** In the SEO dialog, under the `Images Optimization` section, broken images are displayed due to the inclusion of non-editable dynamic template images. This issue has been observed on the appointment and course pages. **Steps to reproduce:** 1. Go to the `Appointment` page on the website. 2. Go to `Site` settings present in the header > `Optimize SEO`. 3. Notice under the `Images Optimization` section, the broken image icon. See [screencast](https://drive.google.com/file/d/1EZTF2FY1ljj6S2PLwwt42Vht1IdVC3aK/view) Exclude non-editable dynamic template images from the SEO dialog's `Images Optimization` section. Users cannot modify their `alt` attributes, so including them serves no purpose. Forward-Port-Of: odoo/odoo#227702
This fix prevents Mexican electronic invoices with external trade details from failing when the USD currency has been deactivated. Businesses can continue confirming and sending affected CFDI invoices without needing to manually reactivate USD first.
Original PR description
**Steps to Reproduce:** 1. Install `l10n_mx_edi_extended` module without demo data. 2. Set company's country to "Mexico" and switch Fiscal Localization. 3. Deactivate USD currency. 4. Configure CFDI…
**Steps to Reproduce:** 1. Install `l10n_mx_edi_extended` module without demo data. 2. Set company's country to "Mexico" and switch Fiscal Localization. 3. Deactivate USD currency. 4. Configure CFDI Certificate and activate Testing mode in PAC. 5. Create a new product with "UNSPSC Category". 6. Create an invoice with CFDI to the public and "Definitive" in External Trade. 7. Confirm and send the invoice. **Sample certificate:** Certificate file: https://drive.google.com/file/d/1kklNGeRtR08erxWRPfIdeiwheDibcB8M/view?usp=drive_link Private key file: https://drive.google.com/file/d/1VJnKVo1doA4cCYPeZBHXKT4JGkbHhOhk/view?usp=drive_link Private key password: 12345678a **Error:** `ValueError - Expected singleton: res.currency()` **Cause:** When sending the invoice, the system attempts to retrieve the USD currency to compute exchange rates. Since the search only considers active currencies, this results in no record being returned, which raises an error in further computation. **Fix:** This commit handles the case when USD currency is deactivated. sentry-6860601127 Forward-Port-Of: odoo/enterprise#94179
This fix makes call status indicators more reliable when joining or recovering a discussion call. It prevents outdated session information from incorrectly muting a user's microphone and ensures warning indicators remain visible when connection data is temporarily reset.
Original PR description
This commit fixes: - the SFU could send outdated information about our own session during the initialisation of the connection. This can lead to the microphone being muted when joining a call if the updates occur when the user rtc session is marked as mute when querying the audio stream. - the warning indicator was hidden if the connection state was undefined this could lead to a missing warning during some recovery steps when session data is reset. Forward-Port-Of: odoo/odoo#228811 Forward-Port-Of: odoo/odoo#228601
Fixed a mobile display issue where product carousel indicators could appear left-aligned when a page first loaded. This keeps storefront product carousels looking polished and correctly aligned for shoppers on smaller screens.
Original PR description
Since the introduction of interactions with [22e777c] in 18.2, the indicators on the CarouselProduct interaction were wrongly computed on mobile: on page load, the indicators appeared on the left instead of centered. This is because an explicit `updateContent()` has to be done at the end of the `updateJustifyContent` method, since it modifies a parameter that impacts the `dynamicContent`. We also take the opportunity to simplify the code of `updateJustifyContent`, which became needlessly complicated after [22e777c]. [22e777c]: https://github.com/odoo/odoo/commit/22e777c046521f3f89b62caa5876680beb7f5aba task-5080057 Forward-Port-Of: odoo/odoo#226632
This update fixes invoice printing for Point of Sale setups that use IoT-connected printers. When an invoice printer is configured, invoices are now sent to the printer instead of only being downloaded, helping cashier workflows continue as expected.
Original PR description
This PR contains two commits, the first is a refactoring, and the second is the invoice printing itself. - **[REF] iot: extract printer select into separate function** Before this commit, the printer…
This PR contains two commits, the first is a refactoring, and the second is the invoice printing itself.
- **[REF] iot: extract printer select into separate function**
Before this commit, the printer selection wizard was tightly coupled to
the IoT report handler, and the call to send to the printer was
duplicated in the wizard and the handler.
After this commit, the printer selection wizard is contained in a
function that will always return the selected printers directly to the
caller, whether the dialog needs to be opened or not. The wizard is
simplified as a result and the print call always occurs in the handler.
This refactoring will allow other places to use the printer selection
wizard, namely for invoice printing.
- **[FIX] pos_iot: print invoices via IoT**
In the commit https://github.com/odoo/enterprise/commit/07418d7544ceecfef38257db8f59bf845a0b0769, the invoice PDF downloading was refactored to
bypass the `ir.actions.report` model, instead working directly via an
action on the invoice model. A side effect of this is that it broke
printing invoices via the IoT, as it relies on the report printing
action to function.
To fix this, this commit introduces an override in `pos_iot` for the
`account_move_service`, which will print the invoice PDF via the IoT
instead of downloading it directly (if a printer is associated with the
report).
task-5109814
Forward-Port-Of: odoo/enterprise#95616
Forward-Port-Of: odoo/enterprise#95586Sign requests opened from a record's chatter now show their related documents in the download menu. This prevents users from seeing an empty download dropdown and ensures they can access the correct signed documents regardless of how they open the request.
Original PR description
Version: - saas-18.4 Steps to reproduce: - Create sign request from 'request signature' activity. - From the chatter of the related record, open the sign request. - It will redirect to form view of that sign request. - click on download dropdown button. Before: - The download dropdown was empty. - This happened because the 'sign_request_documents_dropdown' widget tried to use 'active_id' from the context, but 'active_id' was missing when the sign request was opened from chatter. After: - The download dropdown correctly shows the related documents. - When active_id is not in the context, the widget now uses the sign request id from evalcontext, so it can fetch the right documents. Impact: - Users will always see the correct documents in the download dropdown, even when opening a sign request from chatter. task-5089829
Printed invoices now show the correct early-payment amount when both an early payment discount and cash rounding are applied. This prevents customers from seeing a slightly incorrect amount due on invoice documents.
Original PR description
**Steps to reproduce** - Create a tax of 8.1% - Activate and create a cash rounding with rounding precision 0.05 - Use the existing '2/7 Net 30' payment term (or create a new 2% early discount one) - Create a new invoice: - Add payment terms - Add cash rounding method - Add line with price 50, 8.1% tax - Invoice total will be 54.05 **Issue** Print the invoice: The invoice will show "$ 52.97 due if paid before 09/12/2025" However 52.97 is the amount with just the 2% early payment discount applied With cash rounding applied, it should display 52.95 This occurs because when retrieving the amount from the invoice template the system applies only the early payment discount opw-4914545 [Ticket link](https://www.odoo.com/odoo/project/49/tasks/4914545) Forward-Port-Of: odoo/odoo#228677 Forward-Port-Of: odoo/odoo#225759
This fix prevents Google Calendar account reset actions from failing because of event permission checks. It helps ensure users can reset their calendar connection smoothly without unexpected validation errors.
Original PR description
This commit adds the last context key "skip_event_permission" to the remaining writes done to `calendar.event` records at the reset of google_calendar account, created at odoo/odoo#227991. By adding it, we'll no longer face any possibility of triggering a ValidationError during account resets of google_calendar. task-5103918 Forward-Port-Of: odoo/odoo#228520
Self-service and kiosk orders paid online will now appear on the preparation display only after payment is confirmed. This prevents staff from preparing unpaid orders while still ensuring confirmed orders reach the preparation screen even when customers leave through the payment portal.
Original PR description
pos_*= pos_online_payment, pos_online_payment_self_order, pos_self_order Before this commit, if an online payment method was assigned to a self or a kiosk, the order was displayed on the preparation display before the payment was confirmed. After this commit, the order is no longer displayed on the preparation display until the payment confirmation. Enterprise PR: https://github.com/odoo/enterprise/pull/95312 Backport of https://github.com/odoo/odoo/pull/213493, with additional logic to ensure the order is correctly sent to the preparation display even if an exit route is used in the payment portal --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228687 Forward-Port-Of: odoo/odoo#228189
Orders placed through self-service or kiosk online payment now wait for payment confirmation before appearing on the preparation display. This prevents staff from preparing unpaid orders while still ensuring confirmed orders are sent correctly, including when customers leave via the payment portal exit flow.
Original PR description
pos_*= pos_online_payment_self_order_preparation_display, pos_self_order_iot Before this commit, if an online payment method was assigned to a self or a kiosk, the order was displayed on the preparation display before the payment was confirmed. After this commit, the order is no longer displayed on the preparation display until the payment confirmation. Community PR: https://github.com/odoo/enterprise/pull/87173 Backport of https://github.com/odoo/odoo/pull/87173, with additional logic to ensure the order is correctly sent to the preparation display even if an exit route is used in the payment portal Forward-Port-Of: odoo/enterprise#95583 Forward-Port-Of: odoo/enterprise#95312
Creating a related monetary field in Studio now also creates a linked currency field, so the monetary value remains usable and consistent. This prevents business data entry and reporting issues caused by amounts without a proper currency reference.
Original PR description
Before this commit, when creating a related field to a monetary, the created currency field was not stored and not related either, so the monetary was unusable. This was because of 5cf5a35a0a8f78655989009d0eddcf39f8430965 , b177b058be1531c3d2af2b591c22591c19240d33 and in general the changes in read_group that largely improve the situation. After this commit, we create a currency field related to the currency field of the related monetary to ensure that the monetary's value is coherent. This is made possible by the above mentionned improvements in read_group opw-5094619
Scanning a loyalty card barcode in Point of Sale now correctly selects the customer linked to that card instead of showing an invalid code error. This helps cashiers apply loyalty benefits smoothly and reduces checkout friction.
Original PR description
When scanning the barcode of a loyalty card, there was an error saying the code is invalid. Instead it should select the partner linked to the card if there is one. Steps to reproduce: ------------------- * Create a loyalty program, and a loyalty card with a partner * Copy the barcode of the loyalty card * Open the POS, and scan the barcode of the loyalty card > Observation: The error "Invalid code" appears, and the partner is not selected opw-4653983 Forward-Port-Of: odoo/odoo#215894 Forward-Port-Of: odoo/odoo#213831
Inventory transfers with no valid quantities will now show a clear error instead of opening a backorder step that cannot do anything. This prevents confusing warehouse workflows and helps users correct the transfer before validating it.
Original PR description
### Steps to reproduce: - Create and confirm a delivery with 2 moves: - 1 x product 1 - 1 x product 2 - Set the quantity of product 2 to 0 and mark it as picked - Validate the transfer #### > The…
### Steps to reproduce:
- Create and confirm a delivery with 2 moves:
- 1 x product 1
- 1 x product 2
- Set the quantity of product 2 to 0 and mark it as picked
- Validate the transfer
#### > The backorder wizard open's even though there is nothing to validate. Creating a backorder does nothing.
#### Cause of the issue:
Since there is a picked move, the picking validation does not pick every moves in the `pre_action_done` hook keeping only moves with empty qty as picked:
https://github.com/odoo/odoo/blob/9b41eb38403e64091b74e1ae53c79488aa48b499/addons/stock/models/stock_picking.py#L1208-L1209 Then, only the picked moves are processed in there `_action_done`: https://github.com/odoo/odoo/blob/9b41eb38403e64091b74e1ae53c79488aa48b499/addons/stock/models/stock_move.py#L1914 https://github.com/odoo/odoo/blob/9b41eb38403e64091b74e1ae53c79488aa48b499/addons/stock/models/stock_move.py#L1929-L1937 Which leads to an empty picking validation.
opw-5076640
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#227995The analytic distribution account selector now only shows accounts for the document's company. This prevents users in multi-company setups from viewing or selecting accounts that belong to another company, supporting proper data separation and compliance with company rules.
Original PR description
**Description of the issue/feature this PR addresses:** When creating or editing an analytic distribution, the analytic account selection does not respect the company context. This allows users to…
**Description of the issue/feature this PR addresses:** When creating or editing an analytic distribution, the analytic account selection does not respect the company context. This allows users to see and select analytic accounts from other companies, which violates the multi-company record rules. <img width="669" height="333" alt="2025-09-08_09-28" src="https://github.com/user-attachments/assets/488eb4b1-fdfa-49ca-a57e-8f46a264107d" /> **Current behavior before PR:** The analytic account dropdown in the analytic distribution widget shows analytic accounts from all companies, instead of being restricted to the current company. **Desired behavior after PR is merged:** The analytic account selection in the analytic distribution widget is filtered by company. Only analytic accounts belonging to the document company will be displayed, ensuring compliance with multi-company record rules. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228268 Forward-Port-Of: odoo/odoo#225835
Spanish Mod 349 tax report audits now show the relevant transaction details for the intra-community operations summary line. This helps accounting users verify reported EU invoice amounts instead of seeing an empty audit result.
Original PR description
Steps to reproduce: - With an ES company setup - Create 1 invoice to an EU partner - Make sure Mod349 Invoice Type is set - Go to Accounting / Reporting / Statement Reports / Tax Report - Select Tax Report (Mod 349) (ES) - Audit line 'Importe de las operaciones intracomunitarias' Issue: No line will be shown This occurs because the system will allow auditing the line, since the report line is defined as aggregation of sublines, however those sublines are all custom so we should provide a custom domain to retrieve the relevant lines opw-4752813 Forward-Port-Of: odoo/enterprise#84633
A failing automated test for PayPal button rendering was removed because it depended on real PayPal credentials that cannot be safely used in the test environment. This keeps automated validation stable while the affected PayPal button scenario is handled through manual testing.
Original PR description
## Versions 18.4 ## Issue An error is raised after PayPal SDK call for button rendering in a test introduced by 1b8f26611a1a349a92075720cb95cb17b00c2b21. ## Cause PayPal SDK cannot render a button with dummy credentials. ## Fix As the button requires real (production or sandbox) credentials we cannot safely provide in runbot environment, we accept a manual testing for this specific use case. runbot-232965
The website editor no longer shows ineffective quality controls for WebP images in Safari and iOS webviews, where compression is not supported. This prevents users from expecting image size or quality changes that the browser cannot apply and keeps the editor options consistent when switching image formats.
Original PR description
Scenario: - select a WebP image in the editor - change the quality with the slider Result: - the size and the image quality doesn't change Cause: Safari doesn't support HTMLCanvasElement.toDataURL() with WebP, so the image is exported in PNG instead which is lossless and doesn't support compression. Other issue: If we select in formats a WebP, then a PNG, we still see the quality option that are meant for the WebP, and inversely if we start with a PNG the quality option is hidden. Fix: Disable the quality for WebP images if this is not supported (in safari + iOS webview), and move the code to ImageTools._computeWidgetVisibility so it is updated when we change image type from/to WebP. opw-4979378 Forward-Port-Of: odoo/odoo#223707 Forward-Port-Of: odoo/odoo#223268
Carbon emissions are now calculated using the unit of measure from the emission factor rather than the invoice line. This prevents inaccurate emissions figures and improves the reliability of ESG reporting.
Original PR description
Prior to this commit, the UoM conversion in the carbon emissions calculation was done by targeting the UoM of the account move line instead of the UoM of the emission factor. Which led to incorrect emissions values calculations. task-5107685 Forward-Port-Of: odoo/enterprise#95468
The General Ledger report now correctly lets users expand lines when custom grouping options are used. This fixes a reporting issue that previously hid detailed sublines for non-default groupings, making financial review more complete and reliable.
Original PR description
Before when we added different groupby on the gl line than the default ones, that would not be unfoldable by default. This is due to a default dict that set has_sublines to False by default and it would never be set to true for groupby other than the default ones.
This fixes an issue in the mail module where replacing one item in a related record list could accidentally remove another item. The change helps keep message-related lists consistent and prevents unexpected data loss in affected workflows.
Original PR description
Before this commit, when doing an indexed assignment (`array[index] = record`) on a Many field, it produces an incorrect result where an extra element of the record list would be deleted. This happens because we call a high-level delete on the inverse record before replacing the record, causing the list to shrink in size and causing the indexed assignment to replace the wrong record. This commit fixes the issue by changing the order of the assignment and deletion. fixes task-5090802
The partner ledger now keeps names and expand arrows properly aligned on smaller screens such as phones and tablets. This makes the report easier to read and use when working from mobile devices.
Original PR description
Problem: On smaller screens (phone or tablet) the center alignment between the partner name and the little arrow is broken. Cause: This happened because the little arrow has btn class, which gets larger on smaller screens (to make it easier to click). The larger button causes the center alignment to be lost, as it grows alone inside the table row. Fix: This commit fixes this issue by ensuring that the content of line_name and line_cell are vertically aligned to the middle, and that items in their sub-containers are aligned to the center. task-5106889 Forward-Port-Of: odoo/enterprise#95317