Daily updates from Odoo
Navigate
Branch
Wednesday, July 1, 2026
374 changes
36 changes
New functionality added to Odoo
This update adds two new delivery providers to the Point of Sale integration: Food Zapp for the UAE and Enqueue for Saudi Arabia. It expands the available local delivery options for businesses operating in those markets.
Original PR description
In this commit: - We are introducing two new providers, FoodZapp and Enqueue, for the UAE and KSA, respectively. Task-6263190,6263310 Forward-Port-Of: odoo/enterprise#122001 Forward-Port-Of: odoo/enterprise#121461
Enhancements to existing features
This update records device information when a login appears from a device that does not match the one currently associated with the user session. It helps teams spot suspicious access patterns sooner and strengthens account monitoring without changing the normal login experience.
Original PR description
Log device information if fingerprint doesn't match the one currently being used for the current session. Task-6340963 Forward-Port-Of: odoo/odoo#272413
Resolved issues and error corrections
This fix prevents the AI assistant from retrying a task creation after an error, which could make it look like the same item was being created twice. It also checks that the required fields are present before showing the preview, making the confirmation flow clearer and more reliable.
Original PR description
This commit removes an issue where the LLM would retry on error when performing a creation which would give the impression that it created items twice. To do so, this commit now validates that the fields exists before calling the `create()` method, and before showing the preview to the user. Ensuring it avoids throwing an error after the message has been confirmed (resulting in the double preview). task-6229596 Forward-Port-Of: odoo/enterprise#118044
This change prevents the messaging system from crashing when it receives an unexpected value during subscription. It also makes message recovery more reliable after a database restore, so users are less likely to lose browser session continuity or hit errors in chat-like features.
Original PR description
`_prepare_subscribe_data()` crashes with a `TypeError` when last is not an integer, as the comparison with `_bus_last_id()` is not type safe. Since [1], this can happen naturally: when `_bus_last_id()` returns 0 after a DB restore, `broadcast()` drops the payload due to a falsy check. The tab then stores "undefined" in localStorage, which `parseInt` turns into `NaN`, which JSON encodes as `null`, which the server receives as `None`. Fix the falsy check in `broadcast()` so 0 is not dropped, use `|| 0` instead of `?? 0` when reading localStorage so corrupted values are recovered, and fallback any non integer last to 0 on the server. [1]: https://github.com/odoo/odoo/pull/270317
This update prevents a form error that could occur if a user quickly changed or deleted a field while the page was still loading. It also makes website form testing more reliable, reducing occasional failures in automated checks.
Original PR description
Before this commit, on slow networks users could trigger a traceback by quickly selecting a form field and deleting it. This happened because code executed from `FormFieldOption` `onWillStart` assumed the form field element still existed after awaiting asyncronous functions. This also caused the tour `test_website_form_conditional_required_checkboxes` to occasionally fail on runbot. This commit hardens the method `FormOptionPlugin.loadFieldOptionData` against DOM mutations that may happen while awaiting asyncronous code. In particular, `fieldEl` is now validated after every await. The code is also optimized such that syncronous code relying on the existance of the form field element is executed before the asyncronous one. Note that this change would not be necessary inside builder actions, but it is required because the code is also executed from `FormFieldOption` `onWillStart` and `onWillChangeProps`. runbot-940447
The website generator now matches product categories using unique IDs instead of category names. This prevents mix-ups when different categories share the same label, such as separate Accessories groups for men and women, and makes product setup more dependable.
Original PR description
Before we matched categories with products but names but this was less reliable in the case that we had multiple categories with the same name. e.g. Accessories (for men) and Accessories (for women). This new method allows for this and makes the matching more reliable.
Odoo now supports passkeys on Android devices by linking the website with the mobile app and accepting Android app sign-ins. This makes it easier for users to create and use passkeys from their Android phones while keeping the login flow compatible with Android’s requirements.
Original PR description
This commit adds a route for Digital Asset Links (`assetlinks.json`) that link the domain with the Android Mobile App. Also we adapt some functions authentication/registration so Odoo accept request…
This commit adds a route for Digital Asset Links (`assetlinks.json`) that link the domain with the Android Mobile App. Also we adapt some functions authentication/registration so Odoo accept request origin from the mobile App. The origin should be `android:apk-key-hash:BASE64(SHA256(APP_SIGNATURE))` Note: the `/.well-known/assetlinks.json` file should be serve on port HTTPS (443) without that the Android Digital Asset Links will fail. Url for debugging Digital Asset Links https://digitalassetlinks.googleapis.com/v1/assetlinks:check?source.web.site=https://MY-DOMAIN.local&relation=delegate_permission/common.get_login_creds&target.android_app.package_name=com.odoo.mobile&target.android_app.certificate.sha256_fingerprint=D6:73:20:02:CA:2D:01:C9:FD:FC:94:73:5A:D0:73:CF:2C:36:10:29:1F:4B:F7:5D:91:C2:1D:37:B2:18:E8:91 https://developers.google.com/digital-asset-links https://developer.android.com/identity/passkeys/create-passkeys https://developer.android.com/identity/credential-manager/prerequisites opw-6279212 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270551
This fix ensures subcontracted receipt quantities stay as entered, even after the scheduler runs. It prevents the system from reassigning these moves in the background, which could otherwise overwrite a user's manual quantity adjustment.
Original PR description
**Issue** Quantity on subcontracted receipts could be overridden after running the scheduler. **Steps to reproduce** - Create a subcontracting product - Create a PO for 10 units of that product - Go…
**Issue** Quantity on subcontracted receipts could be overridden after running the scheduler. **Steps to reproduce** - Create a subcontracting product - Create a PO for 10 units of that product - Go to receipt and open Subcontracting Productions' - Change the quantity to 5 - Enable debug mode. - Run Inventory/Operations/Procurement: run scheduler - Return to the receipt -> The receipt quantity is reset to 10 instead of remaining at 5. **Cause** Since the refactor introduced in commit: https://github.com/odoo/odoo/commit/fc66e2d4eb638f1486e69cd5920f02c787055da1, subcontracting receipt moves are no longer automatically picked when the production quantity is modified. In particular, this test case protects that behavior: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp_subcontracting/tests/test_subcontracting.py#L1629-L1631 When the scheduler runs: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/stock/models/stock_rule.py#L731 it computes the moves to assign: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/stock/models/stock_rule.py#L706-L710 However, subcontracting moves are still included in the assignment domain: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/stock/models/stock_rule.py#L680-L688 https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/mrp/models/stock_rule.py#L127-L129 As a result, they are reassigned if they are not already picked: https://github.com/odoo/odoo/blob/f7fb0a941d6bac39b7057db36f57be079559912c/addons/stock/models/stock_move.py#L1931-L1937 opw-6229668 Forward-Port-Of: odoo/odoo#270837
This update stops popup snippets from being added inside other popups or restricted areas, which previously could cause errors and broken editing behavior. It also ensures the snippet list is rechecked after reloads so the available options stay correct for users.
Original PR description
*: website, website_mass_mailing __Problem__ In some cases, popup snippets can be dropped inside another popup. This shouldn't be possible. Moreover, it produces the following error: `TypeError:…
*: website, website_mass_mailing __Problem__ In some cases, popup snippets can be dropped inside another popup. This shouldn't be possible. Moreover, it produces the following error: `TypeError: Cannot read properties of undefined (reading 'after')`. This can happen in multiple scenarios: - After saving a custom snippet, the snippets are reloaded but `disableUndroppableSnippets` is not called again, although the snippets should be filtered again. - `NewsletterPopupPlugin` registers `.o_newsletter_popup` in the `so_snippet_addition_selector` resource, bypassing the more restrictive `dropzone_selector` of `PopupOptionPlugin`. - Popups are not disabled when the cookie bar is open because we don't take `excludeAncestor` into account in `DisableSnippetsPlugin`. __Fix__ - Trigger an event whenever the snippets are loaded and call `disableUndroppableSnippets` when it is. - Remove the redundant `NewsletterPopupPlugin`. - Filter `dropAreaEls` with `excludeAncestor` in `DisableSnippetsPlugin`. Forward-Port-Of: odoo/odoo#272273 Forward-Port-Of: odoo/odoo#269864
This change removes unnecessary product-tracking information from Point of Sale test data and tidies up a couple of automated tests. It also moves stock-related coverage to the stock-specific test area, which makes the test suite easier to maintain and reduces duplicate checks.
Original PR description
*: pos_stock In this commit: --- - Remove the `tracking` field from the HOOT test data. - Remove `test_order_unexisting_lots`, as it is already covered in `pos_stock`. - Move `test_order_existing_lot_gs1_nomenclature` from `point_of_sale` to `pos_stock`, where the stock-related behavior belongs. runbot-941084 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272322
When a vendor bill is completed from a purchase order, some related invoice details can change. This update ensures the linked early payment discount lines are refreshed too, so totals and journal entries stay aligned with the final bill.
Original PR description
When a vendor bill is imported and auto-completed from a purchase order, then invoice lines, taxes, fiscal position, and payment terms can change. Existing EPD dynamic lines that lose their epd_key are skipped by sync and keep stale tax tags and amounts, causing mismatches between Invoice Lines and Journal Items. This commit makes EPD sync include keyless existing EPD lines so they are rewritten or removed during dynamic recomputation after PO auto-complete. Journal items remain consistent with the final invoice lines, taxes, and early discount configuration. Ticket [link](https://www.odoo.com/odoo/project.task/6047505) opw-6047505 Forward-Port-Of: odoo/odoo#272267 Forward-Port-Of: odoo/odoo#265539
Rapidly toggling a website popup could previously leave its visible state out of sync with the on-screen control. This fix makes the popup reliably finish its show/hide transition, which also prevents related issues when creating popups inside other popups.
Original PR description
__To reproduce__ 1. Drop a popup on the website. 2. Click twice rapidly on the popup show/hide toggle in the sidebar. => The popup visibility will be in an inconsistent state compared to the toggle's…
__To reproduce__ 1. Drop a popup on the website. 2. Click twice rapidly on the popup show/hide toggle in the sidebar. => The popup visibility will be in an inconsistent state compared to the toggle's eye icon. __Reason__ Bootstrap ignores any call to show/hide if the popup is still transitioning. __Fix__ - Set `_isTransitioning` to `false` to trick Bootstrap into firing the event regardless of its current state. - When hide/show are triggered in quick succession, the modal can enter an inconsistent state with `.show` class but `display: none` style (hide removes `.show` immediately, show restores it with `display: block`, then hide applies `display: none` after animation). Dispatching `transitionend` event before resetting `_isTransitioning` ensures Bootstrap completes its state transitions. __Note__ This commit also fixes `custom_popup_snippet`, which fails non-deterministically with the following error: `TypeError: Cannot read properties of undefined (reading 'after')` This error occurs when trying to add a popup inside another popup that never closes due to this bug. runbot-939039 Forward-Port-Of: odoo/odoo#269782
Table details now appear correctly in the order info screen for self-orders placed through QR menu or kiosk. This fixes the missing information so staff can more easily identify where an order belongs and handle service faster.
Original PR description
### **Issue** Self-orders created through the mobile QR menu or kiosk were not displaying table information in the Order Info section of the payment screen. ### **Root Cause** The Order Details…
### **Issue** Self-orders created through the mobile QR menu or kiosk were not displaying table information in the Order Info section of the payment screen. ### **Root Cause** The Order Details dialog relied on `order.getTable()` to retrieve table information. However, self-orders only store the table reference through `table_id`, which was not properly handled when rendering the dialog, resulting in missing table information. ### **Solution** This PR introduces the following changes: * Add a dedicated `getTableInfo()` helper in `pos_restaurant` to retrieve table information from the order. * Use `getTableInfo()` when building the Order Details dialog fields. * Allow self-order flows to provide table information through `table_id`, ensuring table details are displayed correctly. ### **Steps to Reproduce** 1. Enable the following options in POS Configuration: * QR Menu & Ordering * Service at Table * Online Payment 2. Open a self-order from the mobile QR menu 3. Select a table and complete the payment 4. Open the POS session 5. Open the paid self-order 6. Click the **Details** button on the right side ### **Video Reproduction** https://drive.google.com/file/d/138AoJCTF1HNlCGFgk9BRTb0UTai-uXX7/view?usp=sharing ### **Before** Table information was not displayed in the **Order Info** section for self-orders. ### **After** Table information is now correctly displayed for self-orders. opw-6179516 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271248 Forward-Port-Of: odoo/odoo#264046
This fix ensures the edit pencil for Suggested Forecasted Demand stays visible even if the Forecasted Stock row is hidden. It prevents an unrelated row filter from affecting access to a forecast adjustment action, making the Master Production Schedule easier to use.
Original PR description
Steps to reproduce:
1. Install Manufacturing.
2. Enable 'Master Production Schedule' in the Settings.
3. Go to [Manufacturing -> Planning -> Master Production Schedule].
4. Ensure 'Demand Forecast' and 'Forecasted Stock' rows are enabled from the dropdown.
5. Observe the edit pencil button next to 'Forecasted Demand' is visible.
6. Hide 'Forecasted Stock' using the rows filter dropdown.
Issue:
The edit pencil button ("Suggest Forecasted Demand") next to the 'Forecasted Demand' row disappears when the 'Forecasted Stock' row is hidden.
Expected behavior:
The edit pencil visibility should not be affected by the 'Forecasted Stock' row.
opw-6240596
Forward-Port-Of: odoo/enterprise#121688
Forward-Port-Of: odoo/enterprise#120208This fix ensures users see the correct manufacturing orders when opening them from the statistics button. It prevents confusion by linking the overview to the actual orders that were manufactured.
Original PR description
* Following https://github.com/odoo/odoo/pull/261438 (forward-ported to 19.0 in #265323) we also need to show correct MOs when view from statsbutton Forward-Port-Of: odoo/odoo#265195 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#269201
This change prevents a crash that could happen when users add properties to a record that also uses computed fields or automatic updates. It ensures the property information is fully ready before the screen is shown, so the action works reliably instead of failing with an error.
Original PR description
Description of the issue/feature this PR addresses: This error occurs when a model has properties and a `computed` field or `onchange` method depends on them. `record.update()` is asynchronous. When…
Description of the issue/feature this PR addresses: This error occurs when a model has properties and a `computed` field or `onchange` method depends on them. `record.update()` is asynchronous. When an onchange or computed field is triggered, an additional request is sent to the server, increasing the time required to complete the update. See: https://github.com/odoo/odoo/blob/727fe7412bb37c1664106625e248264d2aab6809/addons/web/static/src/model/relational_model/record.js#L1207-L1211 However, `PropertiesField` is rendered before the `update` is completed. See: https://github.com/odoo/odoo/blob/727fe7412bb37c1664106625e248264d2aab6809/addons/web/static/src/views/fields/properties/properties_field.js#L86 As a result, the property labels are not yet available and the following traceback is raised: `TypeError: Cannot read properties of undefined (reading 'getRootNode') ` After this commit, the update is awaited before rendering PropertiesField, ensuring that the property labels are available. **Steps to reproduce:** 1. Install the example module. [project_task_property.zip](https://github.com/user-attachments/files/29138424/project_task_property.zip) 2. Open or create a project task. 3. From the Action menu, click `Add Properties`. The error is raised. <img width="1520" height="956" alt="image" src="https://github.com/user-attachments/assets/a3051ddf-5af0-4d3a-8ff7-c3fb4f7a69d2" /> TT63331 @Tecnativa @pedrobaeza --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272653 Forward-Port-Of: odoo/odoo#271082
This update prevents the Italian fiscal printer from getting stuck after the first receipt in Point of Sale. It removes a conflicting print path and keeps receipt printing aligned with the fiscal printer setup, so subsequent printer messages continue to work normally without needing a page refresh.
Original PR description
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview…
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview Screen"; - Disable "ePos Printer"; - Set up an Italian Fiscal Printer; - Open a POS session and process a first order. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Cause: When "Automatic Receipt Printing" is true but "Skip Preview Screen" is false, a race condition occurs. `afterOrderValidation` triggers a print job while simultaneously transitioning to the `ReceiptScreen`. When the `ReceiptScreen` mounts, it triggers a second fiscal print job before the first has resolved. This creates a deadlock in `toHtml` of `renderService`, permanently blocking the printer queue. Solution: Since the italian localisation sending the receipt to the fiscal printer is mandatory, the printing route is now tied to the "Skip Preview Screen" option. UI settings are adjusted to hide the redundant auto-print checkbox when an IT fiscal printer is configured. Community PR: https://github.com/odoo/odoo/pull/256932 [opw-5979212](https://www.odoo.com/odoo/project/49/tasks/5979212) Forward-Port-Of: odoo/enterprise#121779 Forward-Port-Of: odoo/enterprise#112654
This change prevents the Italian fiscal printer from getting stuck after printing the first receipt in POS. It ensures receipts follow the correct printing path so the printer can continue handling later actions like price displays and opening the cash register.
Original PR description
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview…
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview Screen"; - Disable "ePos Printer"; - Set up an Italian Fiscal Printer; - Open a POS session and process a first order. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Cause: When "Automatic Receipt Printing" is true but "Skip Preview Screen" is false, a race condition occurs. `afterOrderValidation` triggers a print job while simultaneously transitioning to the `ReceiptScreen`. When the `ReceiptScreen` mounts, it triggers a second fiscal print job before the first has resolved. This creates a deadlock in `toHtml` of `renderService`, permanently blocking the printer queue. Solution: Since the italian localisation sending the receipt to the fiscal printer is mandatory, the printing route is now tied to the "Skip Preview Screen" option. Enterprise PR: https://github.com/odoo/enterprise/pull/112654 [opw-5979212](https://www.odoo.com/odoo/project/49/tasks/5979212) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272112 Forward-Port-Of: odoo/odoo#256932
The Planning search by skills now correctly shows employees who have the requested skill, even if they have no time slots in the selected period. This fixes a case where valid employees were being hidden from search results.
Original PR description
Issue: ---------------------------------------- Doing a search on skills, the employees with the skill but no slot in the time frame aren't shown. Steps to reproduce:…
Issue:
----------------------------------------
Doing a search on skills, the employees with the skill but no slot in the time frame aren't shown.
Steps to reproduce:
----------------------------------------
- Install `planning_hr_skills`
- Make sure an employee has the skill "English" and no slots
- Open Planning and type "English" in the search bar, click to search on Skills
- The employee does not show up
Cause:
----------------------------------------
Using the search view on skills, a filter on `resource_ids` is in the domain with a `OR`:
https://github.com/odoo/enterprise/blob/5d6d16aae43ffda1532cfa4b06fdcddd7e5b0fcc/planning_hr_skills/views/planning_slot_views.xml#L9
Then a new filter on `resource_ids` is added [here](https://github.com/odoo/enterprise/blob/5d6d16aae43ffda1532cfa4b06fdcddd7e5b0fcc/planning_hr_skills/models/planning_slot.py#L14-L43) to do the search on the skill names: `[('resource_ids', 'in', matching_resource_ids)]`.
The domain is then something like this:
`['&', ('resource_ids', 'in', matching_resource_ids), '|', ('resource_ids', '=', False), ('employee_skill_ids', 'ilike', 'English')]`.
Since fbf8b2ac67c71ca0abfc75df543069696bd2d29b the resulting domain passes through `filter_map_domain()`. `filter_map_domain()` will only keep the leaves on `resource_ids` and the default `AND` will be used between them resulting in:
`['&', ('resource_ids', 'in', matching_resource_ids), ('resource_ids', '=', False)]`
which fetches no resources.
So `_group_expand_resource_ids()` doesn't expand.
Solution:
----------------------------------------
Instead of adding the new leaf to retrieve the resources with the right skills, we replace the leaf on `employee_skill_ids`. This ensures the `OR` operations are kept by `filter_map_domain()`.
opw-6296755
Forward-Port-Of: odoo/enterprise#120669Code blocks in the editor will no longer open command menus or auto-convert text into lists. This avoids errors when users write code and keeps code content unchanged and reliable.
Original PR description
### Steps to reproduce: - Go to ToDo. - Create a code block using `/code`. - Place the cursor inside the code block. - Type `/table` and select the table command. - A traceback occurs. ### Purpose of this PR: - Commands and markdown shorthands should not be available inside code blocks. However, typing `/` inside a `<pre>` opened the command palette, allowing structural commands such as `/table` to be executed and causing a traceback. Similarly, markdown shorthands such as `* ` and `1.` were still active, unexpectedly transforming code content into lists. ### This PR fixes the issue by: - Disabling the command palette when the cursor is inside a `<pre>` element. - Disabling markdown shorthands inside `<pre>` elements by registering an `is_shorthand_available_predicates` predicate. task-6292231 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272271 Forward-Port-Of: odoo/odoo#269430
Imported supplier bill quantities are now kept at the right precision when linking them to purchase orders. This prevents small rounding errors that could slightly overstate invoiced quantities and amounts.
Original PR description
When importing an XML bill and linkin git to a purcahse order, the invoiced quantity may be computed incorrectly, due to a decimal precision mismatch. Steps to reproduce: - Import an XML bill having a line with quantity 1800.0 - Link to a purchase order with the same line Issue: The invoiced quantity will be computed with 1 cent difference (1800.01) Analysis: Because the system forced a decimal precision of 13 for 'Product Unit of Measure', quantity is imported as 1800.0000000000016. Later, when computing the invoiced quantity, the system round the quantity using 'UP' strategy, rounding the amount to 1800.01 opw-6194824 Forward-Port-Of: odoo/odoo#270916 Forward-Port-Of: odoo/odoo#266283
Employees with flexible schedules can now request a single day off on a public holiday when that holiday is meant to count in leave duration. This fixes a case where the request was incorrectly rejected, making behavior consistent with multi-day leave requests.
Original PR description
Currently, flexible employees can request a multi-day leave spanning a public holiday when the leave type includes public holidays in duration. However, requesting the public holiday date alone is…
Currently, flexible employees can request a multi-day leave spanning a public holiday when the leave type includes public holidays in duration. However, requesting the public holiday date alone is rejected. ### **Steps to reproduce:** - Create a public holiday. - Create a time off type with "Public Holiday Included" enabled. - Select/create an employee with a flexible work schedule and its time zone must be same as admin. - Request a time off on the public holiday date only. ### **Observed Behavior:** The request is rejected because its duration is computed as 0 days. ### **Expected Behavior:** The request should be allowed and count as 1 day, consistent with the multi-day request behavior. ### **Root Cause:** At [1], a dedicated duration computation path is used for single-day leaves of flexible employees. This logic always retrieves overlapping public holidays and computes the leave duration based on the remaining intervals. As a result, a leave requested entirely on a public holiday is computed as 0 days, even when `include_public_holidays_in_duration` is enabled. [1]- https://github.com/odoo/odoo/blob/242f6d3cf7288853f163ac6986a3b7aa4279efaf/addons/hr_holidays/models/hr_leave.py#L436-L444 ### **Fix:** This commit ensures that the `include_public_holidays_in_duration` setting is taken into account when computing single-day leave durations for flexible employees **opw-6284768** Forward-Port-Of: odoo/odoo#272217 Forward-Port-Of: odoo/odoo#269743
This update fixes how net cost salary rules are calculated in the UAE and Saudi payroll localizations. It prevents contribution amounts from being dropped or counted the wrong way, so payroll totals stay accurate and consistent.
Original PR description
Steps: - Add a new salary category with the parent_id of company contribution (COMP) in AE - Create a dummy salary rule of that category - Compute a payslip and see the net cost unchanged Or - Create and compute a payslip in SA - Company contributions will be subtracted from each other Issue: - In AE localization, the issue with the rule was dropping salary rules that have a parent of company contribution category - In SA localization, the issue with the NETCOST was the aggregation of individual rules could include negative values which is not the intended flow. Solution: A standardized approach was adopted in both localizations in order to match the calculation of the NETCOST across. This approach will account for the categories with company contribution parent as well as the positive values for the individual salary rules. Forward-Port-Of: odoo/enterprise#120780 Forward-Port-Of: odoo/enterprise#115499
Vendor bills entered in a foreign currency are now matched correctly against GSTR-2B records. This fixes cases where bills were wrongly shown as partially matched even though the GST portal values were correct in INR, helping users reconcile returns without false errors.
Original PR description
**Steps to reproduce:** * Install the **l10n_in_reports** module. * Go to **Accounting → Configuration → Settings**, and enable **Multi-Currencies**. * Activate a foreign currency (e.g., USD) and set…
**Steps to reproduce:** * Install the **l10n_in_reports** module. * Go to **Accounting → Configuration → Settings**, and enable **Multi-Currencies**. * Activate a foreign currency (e.g., USD) and set an exchange rate. * Create a new vendor bill for an Indian vendor, setting the currency to USD. * Add lines to the bill and apply IGST/GST taxes, then confirm the bill. * Go to **Accounting → Reporting → GST Return Period** and initiate GSTR-2B matching for the period corresponding to the bill (using a valid JSON payload where the amounts are correctly reported in INR). **Observed behavior:** * The vendor bill is incorrectly marked as "Partially matched" instead of "Fully matched", accompanied by an exception stating that the total amount as per GSTR-2B does not match. **Cause:** * The GSTR-2B data fetched from the GST portal always reports values in the company's base currency (INR). * The `match_bills` method was directly comparing the GSTR-2B INR amounts ( `bill_total` and `bill_taxable_value`) against the bill's `amount_total` and `amount_untaxed` fields. * Because these fields return values in the document's foreign currency (e.g., USD), the mismatch triggers an exception and flags the bill as partially matched. **Fix:** * Modified the matching logic to compare GSTR-2B values against `abs(amount_total_signed)` and `abs(amount_untaxed_signed)`. * This ensures that the amounts evaluated during reconciliation are always correctly converted and compared in the company's base currency (INR). opw-6311097 Forward-Port-Of: odoo/enterprise#121837 Forward-Port-Of: odoo/enterprise#120967
This update prevents a test from failing in environments where the ISO 20022 payment module is not installed. If the required module is absent, the test is now skipped instead of causing an unnecessary failure, improving reliability of automated checks.
Original PR description
The test_batch_payment_deletion test is currently failing when `account_iso20022` is not installed because the sepa_ct payment method doesn't exists. Add a skipTest in case the module is not installed. runbot-940257 Forward-Port-Of: odoo/enterprise#121511
This change prevents a website error that could happen when adding a dynamic product block to a page. It makes the ribbon assignment logic skip products that do not have a real publish date, so website editing works smoothly even when sample products are used.
Original PR description
Currently, an error occurs when a user insert a dynamic product snippet onto website. **Steps to Reproduce:** - Install `website_sale` without demo data. - Go to `Website` > `eCommerce` > `Products`…
Currently, an error occurs when a user insert a dynamic product snippet onto website. **Steps to Reproduce:** - Install `website_sale` without demo data. - Go to `Website` > `eCommerce` > `Products` > `Ribbons`. - Open any ribbon and set `Assign` to `When New`. - Go to the `Website` > `Edit` > drag and drop the `Catalog` block, and select a `Dynamic Product` block (`Generic Product Template (customizable)` [ref](https://drive.google.com/file/d/1ZYeQA8DhfYAf_jbPwL-tZXaVi1YAyFbd/view?usp=drive_link)). `TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'bool'` After this [recent commit], when a user drops a dynamic product snippet, the system attempts to set the ribbon value [1]. If no product records are available, it falls back to using sample products [2]. These sample products are virtual records created with model.new() [3] [4] and are not stored in the database, so they do not have a publish date. When auto-assigned ribbon with the When New option assign, the system compares the ribbon's new period with the product's publish date. Since the sample products do not have a publish date, this comparison raises an error [5]. This commit ensures that the comparison between new period and publish date is only performed when the product has a valid publish date. [recent commit]: https://github.com/odoo/odoo/commit/f427f795c24ee37ee02302642b77bfc314a9ea43 [1]- https://github.com/odoo/odoo/blob/b70330df7dc2017ab592b075c8ad8e048f671d90/addons/website_sale/templates/snippets/product_snippet_template_data.xml#L52-L58 [2]: https://github.com/odoo/odoo/blob/b70330df7dc2017ab592b075c8ad8e048f671d90/addons/website/models/website_snippet_filter.py#L75-L78 [3]- https://github.com/odoo/odoo/blob/b70330df7dc2017ab592b075c8ad8e048f671d90/addons/website/models/website_snippet_filter.py#L210-L215 [4]: https://github.com/odoo/odoo/blob/b70330df7dc2017ab592b075c8ad8e048f671d90/addons/website_sale/models/website_snippet_filter.py#L62-L95 [5]: https://github.com/odoo/odoo/blob/b70330df7dc2017ab592b075c8ad8e048f671d90/addons/website_sale/models/product_ribbon.py#L121-L124 sentry-7528296918 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268836
This change adjusts an automated Point of Sale test so it uses a safer setup when more than one company is involved. It helps prevent test failures caused by mixing data from different companies, improving reliability of the test suite.
Original PR description
Making the test only depend on one class setup to avoid potential (already present) multicompany issues. In this case the env.user came from one setup class but was incompatible to use during the setup of the second class that was creating records for another company. By making the test only depend on one of the tests we'll avoid this issue. runbot-939375 Forward-Port-Of: odoo/odoo#268819
Debit notes sent to DIAN could fail because the XML included a field that this document type does not support. This fix removes that field for debit notes so the document can be created and submitted successfully.
Original PR description
Issue: Sending Debit Notes to a tax authority can cause the following error: "ValueError: The following child node is not defined in the template: DebitNote/cbc:BuyerReference" Steps to reproduce on…
Issue: Sending Debit Notes to a tax authority can cause the following error: "ValueError: The following child node is not defined in the template: DebitNote/cbc:BuyerReference" Steps to reproduce on any database with DIAN and Colombian localization: 1. Create a new "Sales" type journal. Then, check the checkbox “Nota de Debito”. 2. Find a res.partner with a ref field, or add a ref field to any partner. 3. Make an invoice using the partner found in step 2. Ensure it uses a tax. Confirm it. 4. Send that invoice to DIAN. 5. Create a Debit Note for that invoice. Use the journal created in step 1. 6. Add a product, price, and tax to the debit note. Confirm it. 7. Send the debit note to DIAN. Explanation: The `_add_invoice_header_nodes` method on the AccountEdiXmlUbl_21 model adds a BuyerReference node unconditionally. (See account_edi_xml_ubl_21.py.) But the DebitNote XML template does not include a BuyerReference element (see ubl_21_debit_note.py). This caused a ValueError when assembling the XML for debit note documents. Solution: The fix overrides this in the Colombian localization by clearing the BuyerReference value when the document type is "debit_note". That way, the node is omitted from the output. opw-6181039 Forward-Port-Of: odoo/enterprise#121458 Forward-Port-Of: odoo/enterprise#121422
This fix prevents returned products from being counted as received when the return operation is switched to a different delivery flow. It keeps purchase receipt totals accurate, avoiding incorrect overstatement of quantities received after returns.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Put your warehouse in delivery in 2 steps - On the receipt operation type change the return operation type to be "pick" by…
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Put your warehouse in delivery in 2 steps - On the receipt operation type change the return operation type to be "pick" by default. - Create and confirm a PO for 1 unit of P - Validate the receipt > return > Create the return for 1 unit - Change the operation type of the return from Pick to Delivery to return the product in one step. - Validate the return #### > The qty_received is updated from 1 to 2 instead of 0. ### Cause of the issue: Updating the `picking_type_id` of the return will also update the `location_dest_id` to the default values: https://github.com/odoo/odoo/blob/89807c10c20fb533124b18815f307fc3c380528d/addons/stock/models/stock_picking.py#L1138-L1147 However, the default values of the `Delivery` is "Partner/customer". As such, the location dest of the move is also updated to be "Partner/customer". Now the issue is that the `qty_received` only considers moves to be returned if the location dest usage is not 'supplier': https://github.com/odoo/odoo/blob/89807c10c20fb533124b18815f307fc3c380528d/addons/purchase/models/purchase_order_line.py#L226-L231 https://github.com/odoo/odoo/blob/89807c10c20fb533124b18815f307fc3c380528d/addons/purchase_stock/models/purchase_order_line.py#L55-L67 https://github.com/odoo/odoo/blob/89807c10c20fb533124b18815f307fc3c380528d/addons/purchase_stock/models/purchase_order_line.py#L76-L77 https://github.com/odoo/odoo/blob/89807c10c20fb533124b18815f307fc3c380528d/addons/purchase_stock/models/stock_move.py#L129-L131 opw-6292918 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270571 Forward-Port-Of: odoo/odoo#269867
This change prevents the Intrastat report from failing when a company does not have a country selected. The report now uses the correct fallback value so the query runs successfully instead of stopping with a database error.
Original PR description
When there is no `country_id` on the company we get `False`. The generated query then fail at: ``` ... CASE WHEN (code.country_id IS NULL OR code.country_id = false) THEN code.code ELSE NULL END AS commodity_code, ... ``` with: ``` ERROR: operator does not exist: integer = boolean LINE 12: ... WHEN (code.country_id IS NULL OR code.country_id = false) T... ``` Forward-Port-Of: odoo/enterprise#121798 Forward-Port-Of: odoo/enterprise#121608
The Point of Sale now converts a product’s cost using the correct source currency instead of treating it the same as the sale price. This helps ensure that margin and cost-related figures shown in POS are more accurate when products use different currencies.
Original PR description
When loading products in the POS, both the sale price and the cost were converted to the POS currency using `currency_id`. However a product stores its sale price and its cost in two potentially different currencies: `currency_id` (company currency, falling back to the main company) and `cost_currency_id` (company currency, falling back to the current company). opw-6297452 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269829
This change fixes an error that could prevent the appraisal email template from being read correctly. As a result, appraisal-related emails can be prepared and sent without breaking the workflow.
Original PR description
Task#6309699 Forward-Port-Of: odoo/enterprise#121115
Attendance overtime rules now correctly respect employer tolerance when using timing-based rules. This prevents overtime from being created for short attendances that should fall within the allowed tolerance, improving payroll and attendance accuracy.
Original PR description
**Version:** - 19.0 **Steps to reproduce:** - Create a rule of Timing type. - Add a tolerance for the employer. - Set the ruleset on the employee. - Add an attendance of less than the tolerance. **Issue:** - When using a Timing type rule with employer tolerance, overtime is still created even if the attendance is below the tolerance limit. **Cause:** - The timing rule calculation was missing the tolerance check that exists in the quantity rule calculation. **Fix:** - Added the missing tolerance check in the timing rule calculation. - Removed employee tolerance from view for timing rules. **Task-6064081** Forward-Port-Of: odoo/odoo#271297 Forward-Port-Of: odoo/odoo#257079
The point of sale ticket screen now checks whether an order line is eligible for refund before adding it to a refund. This prevents refund orders from being refunded again and avoids duplicate refunds on lines that were already fully refunded.
Original PR description
In the ticket screen, clicking an order line selected it for refund and incremented its quantity without checking whether the line could actually be refunded. As a result, a refund order (whose lines carry a negative quantity) could itself be refunded, and already fully refunded lines could be refunded again. opw-6314527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271109
This change makes the public chat tour more reliable by ensuring the attachment menu closes before the message is sent. It also corrects a test update so the right conversation is checked between runs, helping prevent flaky test failures and making future debugging easier.
Original PR description
Attempt at fixing the following race condition. It's not clear what causes it, but these changes make the test more robust and might help future investigations. discuss_channel_public_tour opens the composer "More Actions" menu to attach files but feeds the hidden file input directly, so the menu is never closed and is still open when Send is clicked. Close it and wait for it to disappear before sending, to avoid clicking Send while the dropdown is dismissing. Also fix _open_group_page_as_user, which updated the last message body of self.channel instead of self.group between the two tour runs. https://runbot.odoo.com/odoo/error/243436 Forward-Port-Of: odoo/odoo#272606 Forward-Port-Of: odoo/odoo#272425
This update refreshes the spreadsheet component to the latest version and fixes a case where some accounting records use non-numeric identifiers. As a result, spreadsheet pivot data should load and normalize more reliably for affected accounting data.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/e359501309 [REL] 19.4.1 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/e359501309 [REL] 19.4.1 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/5adffa5ca1 [FIX] config: bump node version in GH action [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/feea883b1d [IMP] pivot: give full dimension to pivot normaliser [Task: 6023622](https://www.odoo.com/odoo/2328/tasks/6023622) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
17 changes
Enhancements to existing features
This change speeds up how Odoo retrieves task activity information used by the /mail/data endpoint. By adding a database index, the system can find the relevant records much faster, reducing wait times and improving overall responsiveness.
Original PR description
`/mail/data` is called a lot. It spends roughly 33% of its time on the query fetching task activities in `_get_activity_groups` https://github.com/odoo/odoo/blob/a52b277a4db5f14516717738ca962e3bb3c7180f/addons/project_todo/models/res_users.py#L27 This commit adds an index to speed up the query. - before ~25ms https://explain.dalibo.com/plan/72b26edce8448b51 - after <1ms https://explain.dalibo.com/plan/c4g6851e5b4hh702 task-6327159 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272712
Resolved issues and error corrections
This update fixes the Peru Kardex PLE stock report so it now calculates inventory values and opening balances correctly, even when later purchases change average cost. It also keeps special stock movements, like landed costs, visible in the report without requiring extra dependencies.
Original PR description
*Continuing on the work from https://github.com/odoo/enterprise/pull/111526, new PR because we cannot push to it.* Adapt the Kardex PLE 12.1/13.1 reports from the SVL-based approach in 18.0 to the stock.move-based approach required in 19.0. Key changes: - Use traceable IDs (account_move_id/stock_move_id) for CUO field - Back-calculate opening balance cost at report date instead of using current standard_price, which is wrong when post-period purchases have changed the average cost - Filter storable products only (is_storable) matching v17/v18 behavior - Handle negative opening balance quantities correctly - Add bridge module l10n_pe_reports_stock_landed_costs to show landed costs as separate Kardex lines (operation_type=26) without forcing stock_landed_costs as a hard dependency Forward-Port-Of: odoo/enterprise#121855
The restaurant point of sale now only shows the Split action when bill splitting is turned on in the configuration. This avoids confusing staff with an option they cannot use and keeps the Actions menu aligned with the store’s settings.
Original PR description
Previously, the Split action remained available in the restaurant PoS even when bill splitting was disabled in the POS configuration. Steps to reproduce: - Disable the split bill option in the restaurant POS configuration. - Open a restaurant POS session. - Select a table and add multiple products. - Open the Actions menu. - Observe that the Split action is still displayed. This commit ensures that the Split action is only shown when bill splitting is enabled in the PoS configuration. Task-6294276
Internal notes in Point of Sale now keep the original tag colors when a color has been set, instead of forcing every tag to use the same background. This makes colored notes easier to read and helps staff distinguish tags more quickly in light mode.
Original PR description
Before this commit: ===================== The internal note styling applied a custom background color to all tags, overriding the colors provided by TagsList (o_tag_color_*). As a result, colored tags were displayed with the default background in light mode. After this commit: ====================== The custom background color is applied only to default tags, while tags with an explicit color keep their original TagsList styling. Additionally, demo internal notes were updated with color values to showcase the colored tag behavior. Task:6294250 Forward-Port-Of: odoo/odoo#269746
This update fixes an issue where invoices sent to Viettel S-Invoice could fail when the returned ZIP file had a different structure than expected. The system now correctly finds the XML whether it is directly in the ZIP or inside nested ZIP files, preventing errors and improving reliability.
Original PR description
Description of the issue/feature this PR addresses: The actual XML extraction hardcoded the double-zipped case by reading only the first entry of the outer zip (`zip_file.infolist()[0]`), assuming it…
Description of the issue/feature this PR addresses: The actual XML extraction hardcoded the double-zipped case by reading only the first entry of the outer zip (`zip_file.infolist()[0]`), assuming it was always a nested zip containing the XML. This made it fail when: - The XML was directly in the outer zip (single-zipped). - The zip contained multiple files and the first nested zip didn't hold the XML. Current behavior before PR: After sending an Invoice to Viettel S-Invoice, the e-Invoicing platform would return a ZIP containing one XML file. The XML File being double-unzipped, a traceback is raised. Desired behavior after PR is merged: The fix rewrites _recursive_zip_xml_file_data to actually be recursive. Invoices can be sent to Viettel S-Invoice without raising a traceback. opw-[6249929](https://www.odoo.com/odoo/project.task/6249929?debug=1) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272121 Forward-Port-Of: odoo/odoo#268482
Planning reports can now be printed safely even when grouped by fields like Role or Project instead of Employee. This prevents crashes during report generation and ensures multi-day shifts are handled correctly, improving reliability for users who rely on customized planning views.
Original PR description
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or…
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or `AttributeError`. ### Cause: The `action_print_plannings` method hardcoded the assumption that the `group_by` key would always be a `resource.resource` recordset. 1. When the user grouped by other fields, it returned strings, booleans, or empty recordsets, causing crashes when the code blindly called `.id` and `.display_name`. 2. During the sorting phase, mixing `False` (for unassigned empty recordsets) with strings caused a `TypeError`. 3. For multi-day shifts, the method failed to extract the actual resource to calculate the shift splits if the grouping was not explicitly set to `resource_ids`. ### Fix: - Implement safe attribute checks (`hasattr`) when extracting group IDs and display names. - Ensure unassigned empty recordsets properly fall back to the "Undefined" string and empty strings during sorting to prevent TypeErrors. - Universally fallback to extracting the resource directly from the slot (`slot.resource_ids[:1]`) for multi-day time splitting when grouped by non-resource fields. - Add a unit test to ensure stability when grouping by `role_id` with multi-day shifts. Task: 6244057 Forward-Port-Of: odoo/enterprise#118530
This change prevents an error that could occur when the system looked up an IoT device and found more than one match. It makes device access more reliable by ensuring only one device record is used, avoiding interruptions for users relying on IoT features.
Original PR description
Currently, a singleton error occurs while accessing the `type` field on `iot_device`, as the search assigned to `iot_device` returns multiple `iot.device` records. Error: `ValueError: Expected singleton: iot.device(5, 10)` This commit fixes the above issue by adding `limit=1` to the search, ensuring that `iot_device` always contains a single record and preventing the singleton error. Sentry-7579060623 Forward-Port-Of: odoo/enterprise#122219
This update keeps parent POS orders correctly in sync after repeated split-and-pay actions in the Orders tab. It prevents already paid items from remaining on the draft order, which avoids the same items being charged more than once.
Original PR description
In POS Restaurant with Germany Fiskaly enabled, splitting and paying from a table works once, but repeating the same flow from the Orders tab lets the parent order show lines that were already paid…
In POS Restaurant with Germany Fiskaly enabled, splitting and paying from a table works once, but repeating the same flow from the Orders tab lets the parent order show lines that were already paid in previous splits. Functionally, the cashier can keep splitting and paying the same line again and again because the parent draft order is not updated consistently in that path. Steps to reproduce: ------------------- * Enable POS Restaurant with l10n_de Fiskaly * Create a table order (e.g. 3 meals + 3 drinks) * Open Split Bill, move 1 meal + 1 drink, and pay * From Orders tab, open the remaining parent order and repeat split + pay * Reopen the parent order from Orders tab > Observation: The parent order still contains quantities that were already split/paid, so the same items can be paid multiple times from the Orders tab. Why the fix: ------------ The Fiskaly `syncAllOrders` override diverged from core sync behavior in the split flow: it ignored explicit `options.orders` and did not await transaction creation for inactive transactions. In the split-bill path this could skip or desynchronize parent-order updates, leaving stale quantities on the parent order. The fix restores expected sync semantics by honoring `options.orders` and awaiting transaction creation before deciding sync eligibility. opw-6175880 Forward-Port-Of: odoo/enterprise#117206
This change fixes an issue that could prevent managers from creating a group time off request for multiple employees. If no time-off work type is configured, the system now handles that case safely instead of showing an error.
Original PR description
Currently, an error occurs when a user tries to create a group time off. **Steps to Reproduce:** - Install the `hr_presence` module without demo data. - Go to `Employees` > `Configuration` > `Working…
Currently, an error occurs when a user tries to create a group time off. **Steps to Reproduce:** - Install the `hr_presence` module without demo data. - Go to `Employees` > `Configuration` > `Working Times` > `Time Types` and delete all records. - Make sure there are at least `two employee` records. - Go to `Employees` and switch to the `list view`. - Select `both employees` > click `Presence Control` > click `Create a Time Off`. **Error1:** `TypeError: unsupported operand types in: hr.work.entry.type() | None` **Error2:** `AttributeError: 'NoneType' object has no attribute 'ids'` When a user creates a group time off record and the wizard is opened, it computes the valid work entry types. If no work entry type exists, accessing the `True` key (`requires_allocation`) from the empty dictionary returns None [1]. Later, when performing a union (|) between an empty work entry type recordset and None, it raises the first error [2]. Additionally, accessing ids on None raises the error [3]. This commit ensures that when no work entry type exists, accessing key(requires_allocation) from an empty dictionary returns an empty work entry type record instead of None. [1]- https://github.com/odoo/odoo/blob/374f48cfba75ff98f53d8c3fcc51847711bd406a/addons/hr_holidays/wizard/hr_leave_generate_multi_wizard.py#L144-L145 [2]- https://github.com/odoo/odoo/blob/374f48cfba75ff98f53d8c3fcc51847711bd406a/addons/hr_holidays/wizard/hr_leave_generate_multi_wizard.py#L146 [3]: https://github.com/odoo/odoo/blob/374f48cfba75ff98f53d8c3fcc51847711bd406a/addons/hr_holidays/wizard/hr_leave_generate_multi_wizard.py#L148 sentry-7552717400 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
We fixed an issue where rental and non-rental quotations linked to an opportunity could disappear from the Quotation list. This ensures users can correctly review all expected quotations from the opportunity, improving visibility and day-to-day sales follow-up.
Original PR description
Steps to reproduce: 1. Install sale_crm and sale_renting_crm 2. Create an opportunity 3. On this opportunity, create two quotations from the `New quotation` button 4. From the opportunity's form…
Steps to reproduce:
1. Install sale_crm and sale_renting_crm
2. Create an opportunity
3. On this opportunity, create two quotations from the `New quotation` button
4. From the opportunity's form view, click on the `Quotation` smart button
Issue:
- The quotations are not visible in the list view
Why?
- In module `sale_renting_crm`, we override the domain to exclude rental quotations.
https://github.com/odoo/enterprise/blob/fda037c62a6661665611fb061718c01aec39ac1b/sale_renting_crm/models/crm_lead.py#L33-L36 But from the saas-19.3 `is_rental_order` field is no longer stored in the DB, It is computed now and filtered through `_search_is_rental_order`.
https://github.com/odoo/enterprise/blob/fda037c62a6661665611fb061718c01aec39ac1b/sale_renting/models/sale_order.py#L223-L227 The search method did not properly handle the Boolean search shape used by the ORM, so the quotations were incorrectly filtered out. In our case, we gave the domain `("is_rental_order", "=", False)` but the operator is translated to `not in` and value to `Orderedset([True])` by the domain optimiser
Solution:
- Update `_search_is_rental_order()` to handle the ORM-normalized boolean search correctly for rental and non-rental quotations.
opw-6304696This update refreshes the spreadsheet component and fixes an issue that could prevent certain accounting data from being handled correctly. It improves how spreadsheet pivot tables interpret data, which helps reports display more reliably for affected users.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/040ae04f23 [REL] 19.3.10 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/040ae04f23 [REL] 19.3.10 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/37a0a7031f [FIX] config: bump node version in GH action [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/3412fa57da [IMP] pivot: give full dimension to pivot normaliser [Task: 6023622](https://www.odoo.com/odoo/2328/tasks/6023622) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This fix prevents a crash when translating report XML in Studio on databases where English is not installed. It makes the translation flow more reliable for users working in other base languages.
Original PR description
Init a db with a language different from en_US install other languages, except en_US Try to translate via studio a report's XML This gives a crash, because the baseLang is not installed After this commit, there is no crash. opw-6239938 Forward-Port-Of: odoo/enterprise#122026
When a sign template is duplicated, its roles are now copied as well instead of being shared with the original template. This prevents changes made to one template from unexpectedly affecting another, keeping each template independent.
Original PR description
When duplicating a sign template, its sign items were copied but their `responsible_id` was kept as a reference to the same `sign.item.role` records. As a result, editing a role on one template (e.g. assigning a partner through `assign_to`) leaked to the other template sharing it. Copy the role when copying a sign item so each template owns its own roles. task-6288951 Forward-Port-Of: odoo/enterprise#121411 Forward-Port-Of: odoo/enterprise#119864
This update fixes an internal testing issue in the Point of Sale and Loyalty areas by making temporary test changes automatically clean themselves up. It helps keep the system’s code checks reliable and prevents false test failures during development and validation.
Original PR description
Avoid polluting the Odoo model registry and failing `test_lint_override_signature` by using `patch.object` instead of manual assignment. This ensures the injected method is properly torn down after the test block, keeping the registry clean and bypassing static analysis failure as the patched method is only used for tests. runbot-939298 Forward-Port-Of: odoo/odoo#273096
This change prevents errors when users work with products that do not yet have a generated variant. It hides or blocks inventory-related actions that depend on a variant, avoiding broken forecast, replenish, and on-hand quantity behavior.
Original PR description
Issue: --- Not having at least one variant created for a product template with dynamic attributes can cause issues as it's expected a product template to have at least one variant. To reproduce: 1-…
Issue: --- Not having at least one variant created for a product template with dynamic attributes can cause issues as it's expected a product template to have at least one variant. To reproduce: 1- Create a dynamic attribute with values. 2- Create a product and without saving: - Enable track inventory. - Add the dynamic attributes and values. 3- Save the product. 4- Click on forecasted quantity smart button: - There is a traceback. 5- Click on Replenish: - Unexpected behavior. 6- Click on `Product On Hand Quantity`: - No product will be shown if you try to add quantity. Cause: --- This is caused because there is no variant created. In the steps, if you save the template once before adding dynamic attributes, a single variant will be created which allows it to work without issue. Fix: --- we can fix the TB by hiding the forecasted qty smart button, when there is no variant. However, there will be still issue with `Replenish` flow, which requires a variant. We could do the prevent the issue by ensuring there is at least one variant. opw-6260253 Forward-Port-Of: odoo/odoo#272943 Forward-Port-Of: odoo/odoo#268879
This update adjusts an automated test so it works whether the accounting app is installed or not. It matters because the payment status can now be handled correctly in both setups, preventing false test failures during builds.
Original PR description
If accountant is installed, payment state of unreconciled payment switch from 'paid' to 'in_payment'. Not having accountant break the test. runbot-939445 Forward-Port-Of: odoo/enterprise#121113
This update fixes a test issue in the POS Urban Piper module by making sure temporary test changes are removed properly after the test runs. It helps keep the system’s internal checks stable and prevents unnecessary test failures.
Original PR description
Avoid polluting the Odoo model registry and failing `test_lint_override_signature` by using `patch.object` instead of manual assignment. This ensures the injected method is properly torn down after the test block, keeping the registry clean and bypassing static analysis failure as the patched method is only used for tests. runbot-939298 Forward-Port-Of: odoo/enterprise#122283
7 changes
Resolved issues and error corrections
Internal notes in Point of Sale now keep the intended colors for tags that were already assigned a specific color. This fixes an issue where all tags were forced to the same background in light mode, making colored tags harder to distinguish.
Original PR description
Before this commit: ===================== The internal note styling applied a custom background color to all tags, overriding the colors provided by TagsList (o_tag_color_*). As a result, colored tags were displayed with the default background in light mode. After this commit: ====================== The custom background color is applied only to default tags, while tags with an explicit color keep their original TagsList styling. Additionally, demo internal notes were updated with color values to showcase the colored tag behavior. Task:6294250 Forward-Port-Of: odoo/odoo#269746
This update prevents an error that could appear when the system looks up an IoT device. It ensures only one matching device is used, which helps avoid unexpected interruptions when accessing IoT features.
Original PR description
Currently, a singleton error occurs while accessing the `type` field on `iot_device`, as the search assigned to `iot_device` returns multiple `iot.device` records. Error: `ValueError: Expected singleton: iot.device(5, 10)` This commit fixes the above issue by adding `limit=1` to the search, ensuring that `iot_device` always contains a single record and preventing the singleton error. Sentry-7579060623 Forward-Port-Of: odoo/enterprise#122219
This change fixes a problem where previewing a webhook sample payload could fail for some records. The preview now handles complex field values correctly, so users can view webhook examples without encountering an error.
Original PR description
**Steps to Reproduce:** - Create a Server Action of type 'Webhook Notification'. - Select a model containing a field that returns a `frozendict`-based structure (e.g. `account.move` →…
**Steps to Reproduce:** - Create a Server Action of type 'Webhook Notification'. - Select a model containing a field that returns a `frozendict`-based structure (e.g. `account.move` → `needed_terms`). - Add the field to the webhook fields. - Open the webhook sample payload preview. **Issue:** - During sample payload generation: - The selected fields are read from a sample record. - A selected field returns a structure containing `frozendict` objects. - The payload is serialized using `json.dumps()`. - JSON serialization fails with: ```text TypeError: keys must be str, int, float, bool or None, not frozendict ``` - The webhook sample payload computation crashes and the preview cannot be displayed. **Root Cause:** - The webhook sample payload may contain `frozendict` objects returned by selected fields. - The serializer used for payload generation does not handle such mapping-like objects, causing `json.dumps()` to fail. **Solution:** - Use a serializer that converts mapping-like objects into JSON-compatible structures before serializing the webhook sample payload. **OPW-6295777** 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#272324 Forward-Port-Of: odoo/odoo#271864
This update fixes a spreadsheet issue where some accounting data could not be processed correctly because certain record IDs are text instead of numbers. It helps spreadsheets handle these records properly, improving reliability when working with accounting-related data.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3529978d50 [REL] 19.2.19 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3529978d50 [REL] 19.2.19 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/156b8921dc [FIX] config: bump node version in GH action [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/f3ae8587f9 [IMP] pivot: give full dimension to pivot normaliser [Task: 6023622](https://www.odoo.com/odoo/2328/tasks/6023622) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This change updates a test for Mexican electronic invoicing so it correctly handles a payment that is still unreconciled. It matters because the test no longer fails depending on whether the accounting app is installed, making automated checks more reliable.
Original PR description
If accountant is installed, payment state of unreconciled payment switch from 'paid' to 'in_payment'. Not having accountant break the test. runbot-939445 Forward-Port-Of: odoo/enterprise#121113
This update prevents overtime work intervals from slightly overlapping when times are reconstructed from rounded durations. It improves the accuracy of attendance-based work entries, avoiding small timestamp conflicts that could affect payroll and scheduling records.
Original PR description
__Issue:__ `duration` is rounded to 3 decimals (~1.8s drift) while `time_stop` is exact, so the back-projected start could land before midnight on overnight overtime or middle of the day causing overlaps with the previous line Example: - time_start = 03/05 00:00:00 - time_stop = 03/05 07:07:14 actual duration 7h07m14s gets stored as `duration = 7.121` (= 7h07m15.6s) after `round(_, 3)`. Back-projection yields `datetime_start = 07:07:14 - 7.121h = 02/05 23:59:58`, overlapping by ~2s with the prior line ending at `02/05 23:59:59.999`. __Fix:__ Sort lines by `time_stop` within each date and clamp `datetime_start` to the previously emitted interval's stop when the two intervals genuinely intersect. opw-6170828 Forward-Port-Of: odoo/enterprise#116565
When a new file is uploaded in Documents, its action buttons now appear immediately. This removes the need to deselect and reselect the file just to access available actions, making file handling smoother and faster.
Original PR description
Bug === When uploading a new file in documents, it's selected, but the actions are not visible (we need to unselect - select the record to see the actions). Task-5408471 Forward-Port-Of: odoo/enterprise#122102 Forward-Port-Of: odoo/enterprise#114770
15 changes
Enhancements to existing features
This update adds missing translations across Point of Sale screens, alerts, dialogs, and error messages. It helps users see clearer messages in their language, improving usability and reducing confusion during checkout and payment-related workflows.
Original PR description
pos* = All POS module In this commit: -------------------------------- Add missing translations for user-visible strings across POS modules. - Translated dialogs, errors, alerts, and other UI-visible messages - Updated Python-side UserError, ValidationError, and warning messages Task-5406947 Related PR-https://github.com/odoo/enterprise/pull/102094 Forward-Port-Of: odoo/odoo#272392 Forward-Port-Of: odoo/odoo#239972
This update fills in missing translations for user-facing messages across the Point of Sale apps, including dialogs, alerts, warnings, and error messages. It helps staff see clearer information in their language and makes the POS experience more consistent across supported locales.
Original PR description
pos* = All POS module In this commit: -------------------------------- Add missing translations for user-visible strings across POS modules. - Translated dialogs, errors, alerts, and other UI-visible messages - Updated Python-side UserError, ValidationError, and warning messages Task-5406947 Related PR-https://github.com/odoo/odoo/pull/239972 Forward-Port-Of: odoo/enterprise#121908 Forward-Port-Of: odoo/enterprise#102094
This update makes the POS fiscal integration send customer address information only when it is actually available. It avoids using placeholder values like “N/A”, which helps keep submitted data cleaner and reduces the risk of incorrect information being sent to Fiskaly.
Original PR description
In this commit: ------------------- - Buyer address fields are optional and should only be sent to Fiskaly when they are actually available. - Avoid sending placeholder values like "N/A". If the data is not present, the fields should simply be omitted from the request. task: 6113133 Forward-Port-Of: odoo/enterprise#122188 Forward-Port-Of: odoo/enterprise#113621
When selling products tracked by lot or serial number, the system now automatically applies the correct lot for FIFO/LIFO products and adds them to the cart without extra prompts. If no removal strategy is set, the current selection popup still appears, so existing workflows remain unchanged.
Original PR description
Before this commit: ==== - The lot/serial selection popup was always shown when adding products tracked by lots. Following this commit: ==== - Products configured with FIFO/LIFO removal strategies are automatically assigned the corresponding lot and added directly to the cart without opening the selection popup. - If no removal strategy is configured, the existing lot selection behavior is preserved. task-6226577 Forward-Port-Of: odoo/odoo#265708
Resolved issues and error corrections
This update prevents an error that could happen when a user removes the currency in the payment registration screen. It improves the payment flow for the Argentine withholding setup by avoiding a crash and letting the form handle an empty currency correctly.
Original PR description
When the user removes the currency from the payment register, a traceback is raised. Steps to reproduce the error: - Install ``l10n_ar_withholding`` module - Switch to ``(AR) Exento`` company - Create a new invoice > Confirm > Pay > Unset the currency Traceback: ```py ValueError: Expected singleton: res.currency() ``` https://github.com/odoo/odoo/blob/d98afdc08b46bf458eaa287ea882cc7663286a59/addons/l10n_ar_withholding/wizards/account_payment_register.py#L27 This line causes a traceback with an empty currency when the user removes the currency from the payment register. sentry-7362499567 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272634 Forward-Port-Of: odoo/odoo#255825
Point of Sale internal notes now preserve the original colors of tagged items instead of forcing them into a single default background. This makes colored tags easier to recognize and improves readability, especially in light mode.
Original PR description
Before this commit: ===================== The internal note styling applied a custom background color to all tags, overriding the colors provided by TagsList (o_tag_color_*). As a result, colored tags were displayed with the default background in light mode. After this commit: ====================== The custom background color is applied only to default tags, while tags with an explicit color keep their original TagsList styling. Additionally, demo internal notes were updated with color values to showcase the colored tag behavior. Task:6294250 Forward-Port-Of: odoo/odoo#269746
When a new file is uploaded in Documents, the available actions are now shown immediately after the file is selected. This removes the extra step of deselecting and reselecting the file just to access its actions, making the workflow smoother and faster for users.
Original PR description
Bug === When uploading a new file in documents, it's selected, but the actions are not visible (we need to unselect - select the record to see the actions). Task-5408471 Forward-Port-Of: odoo/enterprise#122102 Forward-Port-Of: odoo/enterprise#114770
This update ensures Romania-specific stock batch behavior is only applied when it should be. It prevents test and system errors caused by those local rules being enabled unconditionally, improving stability without changing normal business flows.
Original PR description
The Romanian specifics were applied without condition which caused runbot errors. Note that this was revealed later on (saas-19.3) after a change in the generic stock test setup. runbot-241098 Forward-Port-Of: odoo/odoo#271985
The Colombian POS test now accepts any valid document number starting with SETF instead of expecting one exact number. This prevents occasional test failures when the same database is reused and the document counter increases.
Original PR description
**Why the fix:** This step failed from time to time as we did some batch testing on the runbot with the same database, and because of this, the Número de Documento increased, making it SETF990000002 or more. This error existed before 68da209 but by fixing the refund flow in said commit, this error has been appearing way more frequently. As this has already happened a few times in 18.2, it is still the targeted version for this fix. We now use a regex to make sure that we have **Número de Documento: SETF** followed by some numbers, but we do not specify that it should be SETF990000001 anymore. runbot-241997 Forward-Port-Of: odoo/enterprise#121211
This update refreshes the spreadsheet component to its latest version and includes fixes for how pivot data is processed. It also improves compatibility with records that use non-numeric identifiers, helping avoid errors when working with certain accounting data.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/44237c04a0 [REL] 19.1.26 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/44237c04a0 [REL] 19.1.26 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/ac1974039f [FIX] config: bump node version in GH action [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/9fa87aa588 [IMP] pivot: give full dimension to pivot normaliser [Task: 6023622](https://www.odoo.com/odoo/2328/tasks/6023622) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update corrects a failing test in the Mexico electronic invoicing flow when the accounting app is installed. It ensures the test accepts the payment status used in that setup, preventing unnecessary runbot failures and keeping automated checks reliable.
Original PR description
If accountant is installed, payment state of unreconciled payment switch from 'paid' to 'in_payment'. Not having accountant break the test. runbot-939445 Forward-Port-Of: odoo/enterprise#121113
This update makes an automated website test self-sufficient by turning on the required free sign-up setting during the test itself. It removes the need for manual configuration before running the test, helping ensure more reliable test results.
Original PR description
Steps to reproduce: 1. Install any website related module (e.g. `website`, `website_event`). 2. Keep the default configuration and do not manually enable 'Free sign up' in setting. 3. Run `test_auth_forms_warning`. Before this commit: The test did not programmatically enable the 'Free sign up' setting. To make the test pass, a developer had to manually navigate to the setting, As a result, it failed on a unless the setting was manually enabled beforehand. After this commit: This commit makes the test self-contained by enabling the required website configuration during its execution, allowing it to run successfully without any manual setup. runbot-233948 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Instagram posts with images will now fail gracefully if the connection times out or another network issue occurs, instead of crashing the server. Users will see a proper failed status, with clearer guidance when the issue is likely caused by a large image taking too long to process.
Original PR description
Making an Instagram containing an image can crash the server with an unhandled `ReadTimeout` instead of marking the post as failed. ### Cause When creating a media container, Odoo passes a URL pointing to its own server and Instagram fetches the image from it server-side before responding. The timeout therefore covers network latency, Instagram's download speed from the Odoo server, and image processing time, making it prone to being exceeded. When it is, `requests` raises a `ReadTimeout` which is unhandled, leading to a raw RPC error instead of a clean `state='failed'`. ### Fix Catch the network errors and mark the post as failed instead of letting them crash the request. Timeouts get a message suggesting a smaller image, since they are usually caused by Instagram fetching and processing a large image server-side. Any other request error falls back to a generic message. opw-6015997 Forward-Port-Of: odoo/enterprise#112573
This change fixes an issue that could make the sales order line screen crash when opening certain order-editing flows. It ensures the product information needed by the unit-of-measure widget is included, so users can load and edit sales lines without encountering an error.
Original PR description
Description of the issue/feature this PR addresses:
- The mandatory product_id field required by the many2one_uom widget was omitted from the list view, causing the issue.
- The issue occurred when the customized 'Extend Order' button was clicked, opening the wizard with all sales order lines loaded into its one2many field.
- Error message: UncaughtPromiseError > OwlError
Uncaught Promise > An error occured in the owl lifecycle (see this Error's "cause" property)
Occured on apollohomecare-migration-v19-33341368.dev.odoo.com on 2026-06-26 10:18:38 GMT
OwlError: An error occured in the owl lifecycle (see this Error's "cause" property)
Error: An error occured in the owl lifecycle (see this Error's "cause" property)
Caused by: Error: The widget 'Many2OneUomField' (field 'product_uom_id') needs a 'product.product' or 'product.template' field. 'product_id' is used but is related to an 'undefined' model.Payslips created from a parent company will now correctly show employees from its Belgian branch companies. This fixes a filtering issue so payroll users can select the right employees without missing branch staff.
Original PR description
Bug: employees registered on branch companies don't appear in the
employee_id field when creating a payslip from the parent company.
Reason: the domain used ('company_id', '=', company_id) which only
matches the exact company, not its children.
Solution: replaced '=' with 'child_of' to include all descendant
companies in the hierarchy.
task - 6299634
Forward-Port-Of: odoo/enterprise#121360
Forward-Port-Of: odoo/enterprise#1209743 changes
Resolved issues and error corrections
This update fixes an issue that could prevent PDF generation for certain Guatemala vendor bills, especially those using the FESP document type with withholding taxes. Users can now download the invoice PDF successfully without encountering errors.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding…
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding 12%` and `ISR Withholding 5%` in Invoice lines. - `Confirm` the bill and `Send to SAT`. - From the gear icon, click `Download` > `PDF`. **Error1:** `KeyError: 'gran_total'` **Error2:** `KeyError: 'retencion_grand_total'` **Root Cause:** In commit [1], the code at [2] missed calling `_l10n_gt_edi_add_base_values()` before `_l10n_gt_edi_add_withholding_values()`. However, `_l10n_gt_edi_add_withholding_values()` uses the `gran_total` value, which is initialized by `_l10n_gt_edi_add_base_values()`, resulting in a `KeyError`. Additionally, the report template at [3] references `retencion_grand_total` instead of the correct key `retencion_gran_total`, causing another `KeyError`. **Fix:** This commit prevents errors and ensures users can successfully download the PDF by applying a fix similar to [4], [1]: https://github.com/odoo/enterprise/commit/44afd19e4ed0827e343af0e584c81e579935c9e8 [2]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L305-L328 [3]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/views/report_invoice.xml#L72 [4]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L790-L800 opw-6323049 Forward-Port-Of: odoo/enterprise#122030
The Helpdesk ticket quick-create form now limits the customer list to the selected company. This prevents users working across multiple companies from accidentally choosing a customer that belongs to a different company.
Original PR description
Steps to reproduce: - Create two companies (Company A and Company B) - Create one partner in each company - Enable both companies for the user - Open Helpdesk and go to the tickets Kanban view for a Company A team. - In the quick create form, the customer dropdown shows customers from Company B Issue: - Customers from other companies are visible in the customer field, Cause: - The partner_id field in the quick create view had no domain, so it displayed partners from all allowed companies. Solution: - Added a domain on partner_id in the ticket quick create form view. task-4971466 Forward-Port-Of: odoo/enterprise#121944
This update fixes a test issue in the Mexico e-invoicing flow when the accounting app is not installed. It ensures the system handles payment status correctly so automated checks no longer fail in this setup.
Original PR description
If accountant is installed, payment state of unreconciled payment switch from 'paid' to 'in_payment'. Not having accountant break the test. runbot-939445 Forward-Port-Of: odoo/enterprise#121113
4 changes
Resolved issues and error corrections
This update ensures Romania-specific stock batch behavior is applied only when appropriate, instead of affecting all cases. It prevents test and build failures caused by those rules being triggered unconditionally.
Original PR description
The Romanian specifics were applied without condition which caused runbot errors. Note that this was revealed later on (saas-19.3) after a change in the generic stock test setup. runbot-241098 Forward-Port-Of: odoo/odoo#271985
The Helpdesk quick-create form now only shows customers that belong to the selected company. This prevents users working across multiple companies from accidentally choosing a customer from the wrong one.
Original PR description
Steps to reproduce: - Create two companies (Company A and Company B) - Create one partner in each company - Enable both companies for the user - Open Helpdesk and go to the tickets Kanban view for a Company A team. - In the quick create form, the customer dropdown shows customers from Company B Issue: - Customers from other companies are visible in the customer field, Cause: - The partner_id field in the quick create view had no domain, so it displayed partners from all allowed companies. Solution: - Added a domain on partner_id in the ticket quick create form view. task-4971466 Forward-Port-Of: odoo/enterprise#121944
This change fixes an issue that prevented users from downloading the PDF of certain Guatemala vendor bills. It ensures the report is generated correctly so businesses can access and share the document without errors.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding…
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding 12%` and `ISR Withholding 5%` in Invoice lines. - `Confirm` the bill and `Send to SAT`. - From the gear icon, click `Download` > `PDF`. **Error1:** `KeyError: 'gran_total'` **Error2:** `KeyError: 'retencion_grand_total'` **Root Cause:** In commit [1], the code at [2] missed calling `_l10n_gt_edi_add_base_values()` before `_l10n_gt_edi_add_withholding_values()`. However, `_l10n_gt_edi_add_withholding_values()` uses the `gran_total` value, which is initialized by `_l10n_gt_edi_add_base_values()`, resulting in a `KeyError`. Additionally, the report template at [3] references `retencion_grand_total` instead of the correct key `retencion_gran_total`, causing another `KeyError`. **Fix:** This commit prevents errors and ensures users can successfully download the PDF by applying a fix similar to [4], [1]: https://github.com/odoo/enterprise/commit/44afd19e4ed0827e343af0e584c81e579935c9e8 [2]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L305-L328 [3]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/views/report_invoice.xml#L72 [4]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L790-L800 opw-6323049 Forward-Port-Of: odoo/enterprise#122030
This update corrects a test in the Mexican e-invoicing flow so it works whether the accounting app is installed or not. It prevents false failures caused by a payment status changing from “paid” to “in payment” in certain setups.
Original PR description
If accountant is installed, payment state of unreconciled payment switch from 'paid' to 'in_payment'. Not having accountant break the test. runbot-939445 Forward-Port-Of: odoo/enterprise#121113
1 change
Resolved issues and error corrections
When creating a Helpdesk ticket quickly, the customer list is now limited to the correct company. This prevents users from accidentally selecting a customer that belongs to another company.
Original PR description
Steps to reproduce: - Create two companies (Company A and Company B) - Create one partner in each company - Enable both companies for the user - Open Helpdesk and go to the tickets Kanban view for a Company A team. - In the quick create form, the customer dropdown shows customers from Company B Issue: - Customers from other companies are visible in the customer field, Cause: - The partner_id field in the quick create view had no domain, so it displayed partners from all allowed companies. Solution: - Added a domain on partner_id in the ticket quick create form view. task-4971466 Forward-Port-Of: odoo/enterprise#121944
7 changes
Enhancements to existing features
The shipping setting formerly called "Batch Shipping" has been renamed to "Multicollo". This makes the wording match Sendcloud’s own terminology and helps avoid confusion for users configuring delivery options.
Original PR description
In order to avoid confusion for the customer, "Use Batch Shipping" was renamed to "Use Multicollo".This way it is consistent with the terminology used by Sendcloud. task-6048477
Resolved issues and error corrections
Printing the Planning report now works reliably even when the report is grouped by fields such as Role or Project instead of Employee. This prevents crashes during PDF generation and ensures multi-day shifts are split correctly in all grouping modes.
Original PR description
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or…
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or `AttributeError`. ### Cause: The `action_print_plannings` method hardcoded the assumption that the `group_by` key would always be a `resource.resource` recordset. 1. When the user grouped by other fields, it returned strings, booleans, or empty recordsets, causing crashes when the code blindly called `.id` and `.display_name`. 2. During the sorting phase, mixing `False` (for unassigned empty recordsets) with strings caused a `TypeError`. 3. For multi-day shifts, the method failed to extract the actual resource to calculate the shift splits if the grouping was not explicitly set to `resource_ids`. ### Fix: - Implement safe attribute checks (`hasattr`) when extracting group IDs and display names. - Ensure unassigned empty recordsets properly fall back to the "Undefined" string and empty strings during sorting to prevent TypeErrors. - Universally fallback to extracting the resource directly from the slot (`slot.resource_ids[:1]`) for multi-day time splitting when grouped by non-resource fields. - Add a unit test to ensure stability when grouping by `role_id` with multi-day shifts. Task: 6244057 Forward-Port-Of: odoo/enterprise#118530
This update corrects the Peru Kardex PLE stock report so it produces more accurate inventory and cost figures. It also ensures landed costs appear properly in the report without adding an unnecessary hard dependency, which improves reliability and compatibility in daily reporting.
Original PR description
*Continuing on the work from https://github.com/odoo/enterprise/pull/111526, new PR because we cannot push to it.* Adapt the Kardex PLE 12.1/13.1 reports from the SVL-based approach in 18.0 to the stock.move-based approach required in 19.0. Key changes: - Use traceable IDs (account_move_id/stock_move_id) for CUO field - Back-calculate opening balance cost at report date instead of using current standard_price, which is wrong when post-period purchases have changed the average cost - Filter storable products only (is_storable) matching v17/v18 behavior - Handle negative opening balance quantities correctly - Add bridge module l10n_pe_reports_stock_landed_costs to show landed costs as separate Kardex lines (operation_type=26) without forcing stock_landed_costs as a hard dependency Forward-Port-Of: odoo/enterprise#121855
This update prevents an error that could occur when the system fetched an IoT device record and found more than one match. It makes the lookup return just one device, improving reliability and avoiding interruptions in IoT-related workflows.
Original PR description
Currently, a singleton error occurs while accessing the `type` field on `iot_device`, as the search assigned to `iot_device` returns multiple `iot.device` records. Error: `ValueError: Expected singleton: iot.device(5, 10)` This commit fixes the above issue by adding `limit=1` to the search, ensuring that `iot_device` always contains a single record and preventing the singleton error. Sentry-7579060623 Forward-Port-Of: odoo/enterprise#122219
Users can now select accounts with the Other Expenses type when creating financial budget lines. This aligns budget setup with all profit and loss accounts, making budgeting more complete and avoiding a selection blocker.
Original PR description
Currently, accounts with the `Other Expenses` account type cannot be selected in financial budget lines. **Steps to reproduce:** - Install the `accountant` module. - Go to `Chart of Accounts` and…
Currently, accounts with the `Other Expenses` account type cannot be selected in financial budget lines. **Steps to reproduce:** - Install the `accountant` module. - Go to `Chart of Accounts` and create a new account with `Type: Other Expenses`. - Go to Accounting > Configuration > Financial Budgets. - Create a new budget and add a budget line. - Try to select the newly created account. **Observation:** Accounts with the `Other Expenses` type are not available for selection in budget lines. **Root Cause:** At [1], the `expense_other` account type is missing from the `account_id` domain. **Expected Behavior:** Financial budgets should allow all Profit & Loss accounts, since the feature relies on P&L reporting. **Reference**: https://www.odoo.com/odoo/project/49/tasks/4314709 **Fix:** This commit ensures that users can add `Other Expenses` accounts to budget lines. [1]: https://github.com/odoo/enterprise/blob/41b66ba081f3938f7e55da209506c637850ae4ec/account_reports/models/budget.py#L114-L120 opw-6313835 Forward-Port-Of: odoo/enterprise#121735
This update corrects button and keypad visibility issues in the Point of Sale ticket screen for certain local setups. It ensures the right controls appear only when they should, and also improves the appearance of a prep-order input field in dark mode.
Original PR description
Issue 1: ====== Numpad Visibility in TicketScreen of draft urban piper orders Steps to reproduce: =================== - Ensure `pos_hr` and `pos_urban_piper` is installed. - Install…
Issue 1: ====== Numpad Visibility in TicketScreen of draft urban piper orders Steps to reproduce: =================== - Ensure `pos_hr` and `pos_urban_piper` is installed. - Install `l10n_in_pos_urban_piper`. - Open a draft Urban Piper order and notice that the numpad is visible. Cause: ====== - The numpad visibility depends on a `t-if` condition in XML. - Due to the asset loading order, this condition gets overridden by another module. Fix: ==== - Move the visibility logic to a getter method. - Override the getter in other modules instead of using XML to control the visibility. - Also fixed the css issue for prep order time input when using it in dark mode --- Issue 2: ====== Invoice button visible on Chile Company's TicketScreen Steps to reproduce: =============== - Ensure `pos_urban_piper` is installed, open the Chile company's PoS Config - In the ticket screen, we have an invoice button on paid orders. Cause: ===== - Button visibility handled through XML conditions; this condition gets overridden by another module. Fix: === - Move the visibility logic to the getter method and override it in submodules to control visibility. Task-6299415 Related Community PR: https://github.com/odoo/odoo/pull/270088 Forward-Port-Of: odoo/enterprise#120571
Quality emails sent to an alias are now correctly turned into quality alerts even when the team’s company was not set. This prevents incoming messages from being lost and helps ensure issues are captured and followed up as expected.
Original PR description
Steps to reproduce 1. Install quality 2. Create an incoming email server 3. Go to Quality > Configuration > Quality Teams > Team > add alias email 4. Do not fill the company field 5. Send email to this alias 6. Fetch emails from incoming email server Issue: - Record is not created in the quality alert Root cause: - For the Quality alert model, the field `company_id` is required, but while we fetch emails We haven't set the `company_id` on the quality alert team, resulting in trying to insert a null value on the quality alert model. Solution: - Give a default value to company_id. - Raise a validation error on not having a company_id - Update alias default values on changing company_id opw-5917791 Forward-Port-Of: odoo/enterprise#121778 Forward-Port-Of: odoo/enterprise#109947
3 changes
Enhancements to existing features
The shipping setting previously called "Use Batch Shipping" has been renamed to "Use Multicollo". This makes the wording match Sendcloud’s terminology and reduces confusion for users when configuring delivery options.
Original PR description
In order to avoid confusion for the customer, "Use Batch Shipping" was renamed to "Use Multicollo".This way it is consistent with the terminology used by Sendcloud. task-6048477
Resolved issues and error corrections
This update fixes a problem in the barcode-based inventory workflow. It helps ensure users can complete stock operations more reliably when using barcode scanning, reducing interruptions during warehouse tasks.
This update makes rental products work properly with Click & Collect in the online shop. It uses the rental period to show the correct availability, improves the add-to-cart experience when items are unavailable, and reduces confusing warning messages for shoppers.
Original PR description
**Purpose:** - Click & Collect and Rental are not working together, the rental dates are not used to display the availability of the product. - Unmute rental period selector when out of stock - Display muted Add to Cart button when out of stock - Remove renting warning message - Select the first valide date when adding to cart from the shop page instead of showing an error message if the product is not available for the default date **Specification:** Create a new bridge module between website_sale_collect and website_sale_renting to ensure that we use the rental dates to compute the availability if this is a rental product. Task-6081690 See also: - https://github.com/odoo/odoo/pull/266874
5 changes
Enhancements to existing features
The customer-facing label “Use Batch Shipping” has been renamed to “Use Multicollo” in the Sendcloud delivery settings. This makes the wording clearer and aligns it with Sendcloud’s own terminology, reducing confusion for users.
Original PR description
In order to avoid confusion for the customer, "Use Batch Shipping" was renamed to "Use Multicollo".This way it is consistent with the terminology used by Sendcloud. task-6048477
This update removes technical e-reporting fields from the standard invoice screen so regular invoicing users see a cleaner, less cluttered view. The relevant e-reporting flow, status, and any blocking issues are still available in the invoice chatter, with a direct link to the related flow when needed. It also stops showing address validation errors on B2C invoices when they are not required.
Original PR description
E-reporting technical fields were displayed directly on invoices, adding noise for regular invoicing users. Hide the e-reporting status columns and technical block from the standard invoice views. Log the relevant e-reporting flow, status and blocking errors in the invoice chatter instead, with a link to the related flow. Also avoid reporting address validation errors on B2C invoices, as they are not required for Flux 10 e-reporting. Task-6273226
Resolved issues and error corrections
This change prevents users from saving default values for fields they do not have permission to modify. It helps keep user settings aligned with access rights and avoids confusion or misuse of restricted fields.
Original PR description
Users should be able to set default values only for fields they have access to. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273089
This fix prevents spreadsheet data from breaking when a linked record uses a text ID instead of a numeric one. It improves reliability for reports and pivots involving those records, so users see correct results instead of import or display issues.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update brings the spreadsheet component to a newer version and fixes a data handling issue that could affect pivot tables and account-related records. It helps spreadsheets display and process certain business data more reliably, especially when records use non-numeric identifiers.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/1a9c76131c [REL] 18.0.73 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/1a9c76131c [REL] 18.0.73 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/9512d92c70 [FIX] config: bump node version in GH action [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/5edfaee5e4 [IMP] pivot: give full dimension to pivot normaliser [Task: 6023622](https://www.odoo.com/odoo/2328/tasks/6023622) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
2 changes
Resolved issues and error corrections
This fix ensures that warning activities created when an orderpoint fails are recorded as coming from Odoo’s system user, not from the customer or portal user who triggered the operation. It prevents incorrect activity history and avoids access issues caused by customer IDs being stored in internal records.
Original PR description
When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `Procurement Exception` and logs a warning activity on the product template. The…
When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `Procurement Exception` and logs a warning activity on the product template. The exception handler uses `.sudo().activity_schedule()`, which bypasses the write access restriction but leaves `env.uid` as the portal user. Therefore, the restricted portal user permanently becomes the `create_uid` (Author) of the activity. System exception activities should always be authored by the system (OdooBot), never by a portal or public user. This context leak corrupts the activity metadata by injecting an external user ID into internal backend logs. Chain `.with_user(SUPERUSER_ID)` to the `.sudo()` call in `stock_orderpoint.py` when scheduling the exception activity. This ensures the environment context is stable and the activity is authored by OdooBot, which transcends multi-company record rules. Steps to Reproduce on Runbot/Fresh Database on version 17.0: 1. Enable Multi-Company with Company A and Company B. Set Company B as the active company for the website. 2. Restrict the main Admin (Runbot) user strictly to Company A. 3. Create a Shared Product (Company field left blank). 4. Set a Reordering Rule (Orderpoint) for the product that is guaranteed to fail routing. 5. Navigate to the frontend website and sign up as a new user (this creates a Portal User in Company B). 6. As the newly signed-up Portal User, complete an eCommerce checkout for the shared product. 7. The checkout succeeds, but the backend triggers the orderpoint failure and logs the exception activity on the product template. 8. Check the chatter for this product: the `create_uid` is incorrectly set to the Portal User instead of OdooBot (1). 9. (In 19.0 Upgrade) Log in as the Admin user (set strictly to view Company A), navigate to the product, and the AccessError for reading will appear due to this leaked id. [opw-6253978](https://www.odoo.com/odoo/my-support-tasks/6253978?debug=assets) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents Odoo from creating one extra recurring event when a Google Calendar series ends on a boundary day in time zones behind UTC. It keeps Odoo aligned with Google so users no longer see duplicate or unexpected events after syncing.
Original PR description
When Google sends a recurrence with UNTIL in UTC (UNTIL=...Z), users in timezones behind UTC can get one extra occurrence on the boundary day. Google's UNTIL represents the last allowed start in UTC, but that UTC date fell into the previous local day. Because Odoo was comparing event start times as naive local datetimes against a cutoff derived from the wrong date, the boundary occurrence passed the check and was created. Steps to reproduce: 1. Set the user's timezone to a UTC-negative offset (e.g. America/Argentina/Buenos_Aires, UTC-3). 2. In Google Calendar, create a weekly recurring event (e.g. every Thursday at 12:00 local). 3. Edit the series with "This and following events" so the old series ends with UNTIL set to 02:59:59 UTC of the next day (= 23:59:59 local of the last valid occurrence day). 4. Sync with Odoo -> an extra event is created on the day after the last valid Thursday, which does not exist in Google Calendar. opw-6024835