Daily updates from Odoo
Monday, June 8, 2026
263 changes
27 changes
Enhancements to existing features
This update clarifies how half-day work periods are displayed on payslips. Previously, half-days were shown as separate entries, creating confusion. Now, the system consolidates these entries for a clearer and more straightforward view of an employee's work time and pay.
Original PR description
In order to clearly distinguish work days that extended full day or half day, the worked days under the payslips will not display both entries as separate types with the half days flagged Task: 5975762 Forward-Port-Of: odoo/enterprise#112328
This update improves the DEP7 export process by switching from PDF to JSON files. This change ensures compliance with BMF (RKSV) requirements and provides machine-readable data for official tools, streamlining reporting and data exchange.
Original PR description
In this commit: ------------------- - Updated the DEP7 export to generate a zip with JSON files instead of PDF, in compliance with BMF (RKSV) requirements. - The export now produces a valid JSON document containing the machine-readable data expected by the official BMF tools. - The filename format has also been adjusted to follow common conventions (e.g. `Name_Duration_DEP_KassenID.json`). Task: 6071034 Forward-Port-Of: odoo/enterprise#112276
Resolved issues and error corrections
This update resolves a technical error that prevented users from correctly configuring billing targets within the timesheet settings. The fix ensures that the system accurately retrieves necessary data for billing calculations, improving the reliability of timesheet reporting. This change was triggered by a necessary update to a core component of the timesheet functionality.
Original PR description
… of employees Prerequisites to reproduce: - Enable `Billing Rate Indicators` in timesheets. - Change timesheet access of user to `User: all timesheets` - Remove Employee access Steps to Reproduce: - In Timesheets app, from configuration go to `Billing Time Targets` - Click on view button on any row Issue: - A traceback breaking the flow. Reason: - We use `hr_presence_status` widget which requires `work_location_type` field, change made from https://github.com/odoo/odoo/commit/0496ed10636c7b2dfde7038a43494d4edbd9f95b. - Thus unavailability of field causing the traceback. Fix: - Add a related field for work_location_type from which we get the value. Forward-Port-Of: odoo/enterprise#97502
This update fixes an issue where online orders with tax included were incorrectly calculating prices. The fix ensures that the unit price accurately reflects the total price, including tax, for transactions using the UrbanPiper integration. This improves order accuracy and provides a more reliable customer experience.
Original PR description
Steps to reproduce: --- - Configure Point of Sale with UrbanPiper credentials. - Sync a product priced at 100 with a 5% GST (tax type = Tax Included). - Place a test order. Issue: --- - Wrong calculation in order line: - unit_price: 95.24 - Tax Excl. price: 90.70 - Tax Incl. price: 95.24 - Expected: - unit_price: 100 - Tax Excl. price: 95.24 - Tax Incl. price: 100 Cause: --- - While computing the unit_price with Tax Included, the tax amount was not added back. Fix: --- - Ensure unit_price includes the tax amount when tax type is Tax Included. task-5031196 Forward-Port-Of: odoo/enterprise#119314 Forward-Port-Of: odoo/enterprise#92854
A recent update caused payment failures in the self-order POS system. This fix corrects a compatibility issue where a new payment method wasn't supported. The change simply ensures the system falls back to the standard POS configuration, restoring payment functionality.
Original PR description
The PR odoo/odoo#267280 changed the Viva class to use the `getCashier` method to determine the `cashRegisterId`, however this method does not exist in self order, so an error is always thrown. This commit fixes the issue by simply adding a `?` so that it falls back to the POS config name. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268548
This update corrects an issue in the l10n_lu_reports module that caused incorrect balance sheet reports. Specifically, fields 2955 and 2956 must always be set to zero, as required by Luxembourg's eCDF reporting standards. Fixing this ensures reports are accepted by the eCDF, preventing data rejection and maintaining accurate financial reporting.
Original PR description
Before this commit, fields 2955 and 2956 in the balance sheet could be incorrect. 2955 must always be blank (not exist) and 2956 must always be 0 per: https://ecdf-developer.b2g.etat.lu/ecdf/forms/popup/CA_PLANCOMPTA/2020/en/2/rules page 116 + 117 If they are not these values specifically, submitting the XML to eCDF results in the report being rejected. Steps to reproduce: - Install l10n_lu_reports - Create a journal entry for a closed year (2025) that debits account 142000 and credits another account that starts with a 1 - Go to the balance sheet for 2025 - Download the XML for the report - 2955 is present and 2956 is either not present or is not 0 (behavior varies between versions) Ticket [link](https://www.odoo.com/odoo/project.task/6246564) opw-6246564 Forward-Port-Of: odoo/enterprise#119193
This update corrects a calculation error in the Swiss Balance Sheet's equity reporting. A new 'Profit / Loss brought forward' line has been added to accurately separate legal reserve and retained earnings, aligning with Swiss accounting standards. The previous 'Annual profit or annual loss' field is now purely informational.
Original PR description
Fix the Equity section in the Swiss Balance Sheet. Adding a new line 'Profit / Loss brought forward' for the result brought forward, that allows to separate the legal reserve and the results. The new structure for the equity section is: - Share, corporate or foundation capital - Legal reserve - Retained earnings - Profit / Loss brought forward - Previous years' unallocated profit or loss - Treasury shares The 'Annual profit or annual loss' is now purely indicative and is not taken into account in the equity computation, as the amounts in this section are considered in the new Retained Earnings section. task-6220525 Forward-Port-Of: odoo/enterprise#117601
A recent update to the enterprise modules caused a minor issue with Odoo's menu loading tests. This change has been fixed by adjusting the expected query counts in the tests to match the new system behavior. This ensures the tests continue to run successfully and accurately reflect performance.
Original PR description
Due to fix in enterprise modules introduced an additional query during menu loading. As a result, the menu loading tests started failing because their expected query counts are hard coded. Update the affected tests by increasing the expected query count by one. task-6236300
This update fixes an issue preventing standard users from accessing timesheet configuration options and sharing rules with higher-level users. The change ensures all users with appropriate access, including those with 'All Timesheets' permissions, can effectively manage and share timesheet rules.
Original PR description
Issue 1: Assistant Rules inaccessible to standard users Steps to Reproduce: - Install sale_timesheet. - Disable the "Billing Rate Indicators" setting. - Log in as a user with only "Own Timesheets"…
Issue 1: Assistant Rules inaccessible to standard users Steps to Reproduce: - Install sale_timesheet. - Disable the "Billing Rate Indicators" setting. - Log in as a user with only "Own Timesheets" access. - Open the Timesheets app. Current Behavior: - The Configuration menu is completely hidden, making Assistant Rules inaccessible to the user. Cause: - When sale_timesheet is installed, the "All Timesheets" access restriction is inaccurately applied to the main Configuration parent menu rather than specifically targeting the Billing Rate child menus. - The Configuration menu is blacklisted using a strict AND condition, requiring the user to have the Use Assistant group and hold a Timesheets Admin / Administrator / Technical Features role. This prevents standard timesheet users from configuring their own rules. Fix: - Remove the "All Timesheets" access restriction from the parent Configuration menu and apply it directly to the Billing Rate menus instead. - Update the blacklisting logic to use an OR condition, ensuring the configuration menu is visible if a user has Admin access to timesheets or belongs to the Use Assistant group. --- Issue 2: Unable to share rules with higher-level users Steps to Reproduce: - Create a user with "All Timesheets" access. - Open the Timesheets app and navigate to Assistant Rules. - Attempt to share any rule with the newly created user. Current Behavior: - The new user is missing from the dropdown selection list. Cause: - The domain on the user selection field filters based on explicitly assigned groups (using group_ids for "Own Timesheets" access). Users with higher-level access, such as "All Timesheets" or "Timesheets Admin", have this access implied rather than explicitly assigned, meaning it only registers in `all_group_ids`. Fix: - Update the field domain to evaluate `all_group_ids` instead of `group_ids`. This ensures users with implied group access are correctly populated in the dropdown list. task-6236300
This update resolves a bug that prevented users from creating new social media posts when no social account was configured. The fix ensures the system handles scenarios where the message field is read-only, preventing a crash related to measuring the textarea's dimensions. This improves the reliability of the social media posting feature.
Original PR description
Steps to reproduce: 1. Install social module 2. Keep no social account set 3. Create a new post by social media > posts menu > new Issue: We got a traceback saying: `OwlError: An error occured in the owl lifecycle (see this Error's "cause" property) TypeError: Cannot read properties of null (reading 'getBoundingClientRect')` Cause: When no social account is set, the message field renders in read-only mode, so the <textarea> is never mounted, and textareaRef.el is null. The useEffect tracking the textarea's width fires and crashes. https://github.com/odoo/enterprise/blob/77be4285785f9d8a462b99b23185a9aefeae4482/social/views/social_post_template_views.xml#L37-L41 Solution: Add a null guard on textareaEl inside the useEffect callback so that the width computation is skipped when the textarea is not present in the DOM. opw-6218431
This update fixes a technical error that was preventing warning messages from being logged correctly in the IoT module. The issue stemmed from how data was being passed to logging functions, and this change ensures all warning messages are properly recorded for monitoring and troubleshooting.
Original PR description
Error: ``` TypeError: Logger._log() got an unexpected keyword argument 'ip' ``` Cause: - The `**new_iot_record` unpacks the dictionary into keyword arguments for `Logger._log()` instead of supplying it as the value for the third `%s` placeholder in the warning message, causing the error because `_log()` doesn't accept keywords such as `version` or `ip`. sentry-7522168864 Forward-Port-Of: odoo/enterprise#119494
This update resolves an issue preventing correct calculation of the 13th month salary in the Belgian localization. The fix ensures the forced variable salary is properly applied during payslip computation, addressing a previous type error that disrupted the process.
Original PR description
Steps to reproduce: * Create a new payslip in belgian localization * Set pay structure type to 13th month * Set the input value for the forced variable salary * Compute the payslip sheet Issue: * Despite the change of benefits to properties, the avg_variable_revenues was still being set as one of the benefit lines instead of ref_property value which was causing an type_error traceback Solution: A simple approach is to be followed to retrieve the value fo the forced variable salary from the actual property being set by the user at the payslip form view and will be accounted for in the payslip computation. Task: 6241608 Forward-Port-Of: odoo/enterprise#118644
This update fixes an issue where half-day absences were incorrectly rounding up hours, leading to inaccurate payroll calculations for employees using flexible schedules. The change decouples the scheduling logic, now accurately splitting half and full days based on defined hours per day, ensuring correct payroll processing.
Original PR description
Steps: - Create half day off for an employee - Create a full day off of the same type - Create a payslip for the employee Issue: - Due to the lack of attendance hours in the flexible schedules, the _get_work_hours_split_half is unable to split half day and full days work entries of the same type. - Half worked days will be rounded up which affects the total number of work days in a month Solution: The approach was to decouple the work_hours_split_half functionality from the attendance hours and rely on the specified hours_per_day instead. This accurately splits half and full days. Task: 6253675 Forward-Port-Of: odoo/enterprise#118836
This fix ensures that account moves generated during inventory valuation use the correct branch company (Branch A) instead of the parent company (Company A). This resolves an access error that occurred when navigating to the inventory valuation view, ensuring accurate financial reporting for branch operations.
Original PR description
**Steps to reproduce:** - create a new company A - in the branch tab, create a new branch A for this company - create a warehouse for the company A and a warehouse for the branch A - from the company…
**Steps to reproduce:** - create a new company A - in the branch tab, create a new branch A for this company - create a warehouse for the company A and a warehouse for the branch A - from the company A, in settings for the 'fiscal localization' set Package : Generic Chart of account, if not already set (to have account journals). From the branch A: - create a storable product with standard perpetual category - set a cost of 10 - confirm a PO for 10 and validate delivery - navigate to 'inventory valuation' Make sure the branch A is the main company, but both branch A and company A are selected: - click on generate entry - click on the 'Other Info' tab **Current behavior:** The company of the account move is the parent company (Company A) **Expected behavior:** It should be the branch A. (As it is the case if only branch A is selected when clicking on "Generate entry") IAs a consequence, f you click on 'Inventory Valuation' on the top left to go back to the view, you will have an access error. **Cause of the issue:** When computing the company_id on the account move, move.journal_id.company_id will be the parent company because the journal_id of the branch is the one of the parent company (by default). So we will call _accessible_branches() on the parent company. https://github.com/odoo/odoo/blob/661ddbb7f12e32394a3c11b5a4cd2f38a9e156f5/addons/account/models/account_move.py#L878-L881 Inside __accessible_branches(), 'accessible' will be based on self.env.companies https://github.com/odoo/odoo/blob/661ddbb7f12e32394a3c11b5a4cd2f38a9e156f5/odoo/addons/base/models/res_company.py#L430-L439 (which is based on 'allowed_company_ids' in the context. https://github.com/odoo/odoo/blob/661ddbb7f12e32394a3c11b5a4cd2f38a9e156f5/odoo/orm/environments.py#L266) So the return value of __accessible_branches() will be a list with 2 ids, the one of the parent company and the one of the branch. And we will use the first element of this list, which will be the parent company_id, in _compute_company_id to set the company of the account move. **fix:** When fetching the data for the inventory valuation view, only the data from the main company selected matters, https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/report/stock_valuation_report.py#L13 The idea of the fix is to do the same in action_close_stock_valuation when creating the account move. We already did something very similar in this PR https://github.com/odoo/odoo/pull/262776 where we also modified the context in action_close_stock_valuation() before calling _action_close_stock_valuation() https://github.com/odoo/odoo/blob/43f5ceadbc1f7df9898c327bf65bffdbe9860c1c/addons/stock_account/models/res_company.py#L56 opw-6144294 Forward-Port-Of: odoo/odoo#266776 Forward-Port-Of: odoo/odoo#263828
This update resolves a technical error that was preventing the POS HR module from functioning correctly in certain situations. The change replaces a problematic data source with a more reliable one, ensuring consistent performance and stability for users. This fix addresses a potential issue that could have caused errors and disruptions.
Original PR description
`pos.config.current_session_id` is a computed field from the backend. In some cases, it's possible that we don't have this field causing the following error
```
TypeError: undefined is not an object
(evaluating 'this.config.current_session_id.id')
```
task: https://www.odoo.com/odoo/project/1737/tasks/6253422
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#267225
Forward-Port-Of: odoo/odoo#266858A technical issue preventing leave requests created on weekends was fixed. This update ensures that leave requests are correctly processed regardless of the day of the week, improving the reliability of the HR system. The fix addresses a test failure related to weekend scheduling.
Original PR description
Fix a test that creates a leave to ensure this leave is created. During week-ends, the test would fail as it was out of the employee's schedule runbot error 242476
This update resolves a technical issue that caused delays during Odoo's initial startup process. By optimizing how reference units are fetched, the system now loads more reliably and efficiently, reducing potential startup problems. This change also minimizes unnecessary network requests, improving performance and stability, especially in offline environments.
Original PR description
…race The `setup()` lifecycle hook executes synchronously, meaning the initial `orm.searchRead()` calls to fetch the reference unit and rounding digits could not be awaited. As a result, the component would finish rendering before the RPC responses arrived, which could lead to timing issues during initialization. Additionally, `onWillUpdateProps` would refresh the reference unit on product property updates even outside of an active search context, leading to extra RPC traffic. In offline scenarios, this could result in unexpected blocking behavior for non-cached network requests. To streamline this process, the fetch logic has been moved into `search()` so the reference unit is resolved only when required. We also switch to `orm.read()` since the target IDs are already available, and cache the `decimal.precision` results to minimize redundant RPCs.
This update resolves an issue where activity labels in the chatter interface weren't showing correctly when the default summary was removed. The fix ensures that activity labels now consistently pull from the 'display_name' field, providing accurate and complete labels for all activity updates. This improves the user experience and ensures consistent information display.
Original PR description
Before this commit: --- - Chatter activity display used [`summary`](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/static/src/core/web/activity.js#L42) to get…
Before this commit: --- - Chatter activity display used [`summary`](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/static/src/core/web/activity.js#L42) to get the display name. - If `summary` was empty, it fell back to [`display_name`](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/static/src/core/web/activity.js#L44). - However, `_to_store` only [stored](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/models/mail_activity.py#L680) `summary`. - As a result, nothing was shown when `summary` was empty, even though `display_name` was set. Steps to reproduce: --- - Create an activity in chatter - Remove the default summary if set. - Observer the title. https://github.com/user-attachments/assets/1684feb7-02d0-4ac1-9c00-d2aaae88e045 After this commit: --- - Added `display_name` to `_to_store` along with `summary`. - Chatter activity now correctly falls back to `display_name`. - Users can now see the correct activity label in chatter. OPW: 6212976 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267555 Forward-Port-Of: odoo/odoo#266706
This update fixes an issue where adding a new attribute to a product template would reset the manually set prices on its variants back to the base template price. The fix ensures that variant prices remain as they were originally set, preserving user-defined pricing. This prevents disruption to existing product configurations.
Original PR description
**Problem:** Adding a single-value attribute to a product template that has variants with manually-set sales prices wipes those prices, resetting each variant back to the template's base list_price.…
**Problem:** Adding a single-value attribute to a product template that has variants with manually-set sales prices wipes those prices, resetting each variant back to the template's base list_price. **Steps to reproduce:** 1. Create a template "Cable" with attribute Length [1m, 5m, 10m, 15m] (template list_price=1.0). 2. On each variant, manually set a unique Sales Price (10/20/30/40). 3. Add a single-value attribute (e.g. Brand=MELODIKA) to the template. 4. Observe variant Sales Prices. **Current behavior:** All four variant prices are reset to 1.0 (the template list_price). Variant ids are unchanged. **Expected behavior:** Variant prices remain at the manually-set values, since no variant is created or removed. **Cause of the issue:** In 19.x, product.product.lst_price is a stored compute with readonly=False, allowing per-variant overrides. The single-value branch of product.template._create_variant_ids writes product_template_attribute_value_ids on each existing variant to attach the new attribute. That write invalidates the variant's price_extra (One2many depends), which in turn invalidates the stored lst_price compute. On the next flush, lst_price is recomputed as list_price + price_extra, overwriting the user override. **Fix:** Snapshot each variant's lst_price before the single-value-attribute write loop and restore the snapshot afterwards if the recompute changed it. This preserves user-set per-variant prices in the case the loop already exists to handle (single-value attribute that does not require recreating variants). Trade-off: if the single-value attribute itself carries a non-zero price_extra and the user had manual overrides, the extra will not auto-propagate to overridden variants. That is preferable to wiping the override entirely, which is the reported regression. opw-6229147 Forward-Port-Of: odoo/odoo#265786
A bug was preventing users without Live Chat access from viewing visitor reports. This was caused by a misconfiguration in how the system checks user permissions for accessing Live Chat data. This fix ensures that users without Live Chat access can still access basic visitor reports.
Original PR description
**Steps to Reproduce** 1. Open a database in version 19.2 with demo data. 2. Install the `website` and `im_livechat` modules. 3. Login with another user who has access to the Website application but…
**Steps to Reproduce**
1. Open a database in version 19.2 with demo data.
2. Install the `website` and `im_livechat` modules.
3. Login with another user who has access to the Website application but does not have access to the Live Chat application.
4. Navigate to: **Website → Reporting → Visitors**
5. An `AccessError` is raised with the traceback below.
**Issue:**
The traceback is caused by the following [commit](https://github.com/odoo/odoo/pull/240778/changes#diff-580c2ced97a218f926605037b31c4fd2d01253eb1b4f290038f251f9ef31be3b) introduced in v19.2.
In this commit, a new [computed field](https://github.com/odoo-dev/odoo/blob/381aede4fde0f871b51df41911c28be3153cd489/addons/website_livechat/models/website_visitor.py#L32) `current_livechat_agent_ids` was added on `website.visitor`.
Inside this compute, data from `im_livechat.channel.member.history` is accessed using `_read_group`.
However, `im_livechat.channel.member.history` is only accessible to users belonging to the following group: `im_livechat.im_livechat_group_user`
At the same time, the Website Visitors menu is accessible to normal Website users through the Website module [ACLs](https://github.com/odoo/odoo/blob/006a6a1cc6e50bd8b328d0cabb7abbcf610e34bb/addons/website/security/ir.model.access.csv#L30)
The issue occurs because the same `website.visitor` views/actions are reused from multiple menus (Website, Social Marketing, Live Chat), but the compute method assumes that the current user has Live Chat access.
As a result, when a user without Live Chat permissions opens: **Website → Reporting → Visitors**
the compute of `current_livechat_agent_ids` triggers an `AccessError`.
**Solution:**
To fix this issue, a group access added on the field `current_livechat_agent_ids`
**Traceback:**
```python
File "/home/odoo/src/odoo/saas-19.2/addons/
website_livechat/models/website_visitor.py", line 32, in
_compute_current_livechat_agent_ids
self.env["im_livechat.channel.member.history"]._read_group(
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 1933, in
_read_group
self.browse().check_access('read')
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 3373,
in check_access
raise result[1]()
odoo.exceptions.AccessError: You are not allowed to access
'Keep the channel member history' (im_livechat.channel.member.history) records.
This operation is allowed for the following groups:
- Live Chat/User
Contact your administrator to request access if necessary.
```
opw : 6169395
upg : 4286153, 4286493, 4283345
tbg : 2676
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#265534This update fixes a potential error in the payment authorization process. It prevents issues that could arise when entering excessively long addresses during credit card payments via Authorize.net, ensuring data compatibility with the payment gateway's requirements. This improves the reliability of payment processing.
Original PR description
Steps to reproduce: - install payment_authorize module; - complete a credit card payment using Authorize.net with more than 60 characters on any other field than first name, last name or company; - confirm the payment. Issue: An error message appears. Cause: The Authorize.net API define the max length of information. It is possible that some information exceeds the maximum length. (https://apitest.authorize.net/xml/v1/schema/AnetApiSchema.xsd) Solution: Truncate information if the number of character is too large. opw-6141441 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262154
This update resolves a problem where the size of country flags on the Visitors reporting page was changing unexpectedly, particularly after installing the livechat app. The fix also ensures that flags set through Studio remain visible and responsive to size adjustments, preventing them from disappearing.
Original PR description
The website.visitor.view.kanban view uses the o_country_flag class which is not defined anywhere besides livechat_channel_info_list.scss. This causes unintended behavior where the flag size for the kanban view on ' Website > Reporting > Visitors ' changes when installing the livechat app. Additionally, the image_url_field.js file does not address cases when height/width are not set. This results in the flags (or any other image using 'widget="image_url"' disappearing (being set to a 'width: 0px') whenever their Size is set via Studio. This change makes it so that the flags don't disappear when altered in Studio (but does not make them actually respond to size changes) Related tickets: opw-5962151, opw-5995004 Forward-Port-Of: odoo/odoo#251618
This update resolves an issue where the IRN (Invoice Reference Number) wasn't being saved correctly when sending invoices via e-invoicing with email in the Indian localization. The fix ensures the attachment ID is saved, guaranteeing the IRN is included in the email and associated with the invoice. This improves compliance and accuracy of e-invoicing processes.
Original PR description
**Issue**: Sending invoice through e-invoicing with email in Indian localization will not save the IRN number on the invoice because of a cache issue on the attachment id. **Steps to reproduce**: Install l10n_in_edi_gstr module. Create an invoice and send it through e-invoicing with email option. The IRN number will not be saved on the invoice. **Causes**: When sending the invoice through e-invoicing with email option, the attachment id is not saved on the invoice before calling the method _l10n_in_edi_send_invoice(). This causes a cache issue and the IRN number is not saved on the invoice. **Fix**: Save the attachment id on the invoice after the creation of the attachement. opw-6243256 Forward-Port-Of: odoo/odoo#268595 Forward-Port-Of: odoo/odoo#268285
This update resolves an issue where applying discounts on products with different taxes caused an endless checkout reload. The fix ensures discount lines are grouped correctly, synchronizing the backend and frontend to prevent the reload loop and improve the shopping experience.
Original PR description
**Step to reproduce :** 1. Create a deliverable product with a sales tax. 2. Create another product with a different sales tax. 3. Publish both products on the eCommerce website. 4. Create a discount…
**Step to reproduce :**
1. Create a deliverable product with a sales tax.
2. Create another product with a different sales tax.
3. Publish both products on the eCommerce website.
4. Create a discount program.
5. Add both products to the shopping cart.
6. Apply the discount code.
7. Proceed to checkout.
**Issue :**
Applying a discount on multiple products with different taxes causes an infinite reload cycle during checkout.
**Reason :**
The reload is supposed to sync the discount lines in the back-end with the discount lines displayed during checkout. If the number of lines don't match, a reload is triggered.
https://github.com/odoo/odoo/blob/18.0/addons/website_sale_loyalty/static/src/js/checkout.js#L22-L24
After the fix introduced in:
https://github.com/odoo/odoo/pull/248215
However, when a discount is applied to products with different taxes, the corresponding reward lines are still categorized as `discounted_lines` instead of `groupable_lines`. As a result, they continue to be processed individually rather than being grouped by reward.
This leads to a mismatch between the backend, which generates one discount line per tax combination, and the frontend, which expects a single discount entry per reward. Consequently, the checkout page continuously reloads while attempting to synchronize both states.
**Solution:**
When a discount applies to products with different tax configurations, the corresponding reward lines should be included in `groupable_lines` rather than `discounted_lines`. This ensures that discount lines are grouped by
`reward_id` consistently on both the frontend and backend, preventing the checkout reload loop.
opw-6210411
Forward-Port-Of: odoo/odoo#265740This update resolves an issue where enabling the 'Sales Credit Limit' setting caused an access error when creating new users. The problem stemmed from a default value being incorrectly applied to a restricted field due to inheritance within the system. This fix ensures the system functions correctly with the new setting enabled.
Original PR description
# How to reproduce - Install the Accounting module - In the settings, enable "Sales Credit Limit" - Remove the Accounting access rights of the current user - Try to create a new user # The issue An…
# How to reproduce - Install the Accounting module - In the settings, enable "Sales Credit Limit" - Remove the Accounting access rights of the current user - Try to create a new user # The issue An access error is raised on the field `credit_limit` # Cause Enabling the "Sales Credit Limit" setting will create an `ir.default` for the `credit_limit` field. This field is restricted to a specific group : https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/addons/account/models/partner.py#L515-L518 When creating a record, we check field permissions before adding default values, so the creation of the user is fine. However, since `res.users` inherits from `res.partners`, a new partner will also be created, but this time with the default values in `vals_list`, which will trigger an access right error. # Proposed solution Back port of this commit : https://github.com/odoo/odoo/pull/267193 Access right checks when creating a record were introduced in 18.3 by : https://github.com/odoo/odoo/commit/15132342960df76fcefd3284a9eff2d4d3273150 opw-6240494 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268303 Forward-Port-Of: odoo/odoo#268039
This update resolves a technical error that could occur when calculating rental availability for products with start and return dates. Specifically, it prevents a traceback when dates are incompatible, ensuring accurate availability information is displayed to customers on product pages. This improves the overall rental booking experience.
Original PR description
Preventing traceback on incompatible dates between the cart and the product page. How to reproduce: 1. Add to cart a product with periodicity Hours/Days with a start date = return date (e.g.: Projector). 2. Go to the product page of a product configured with Pickup > Return (e.g.: Premium Bike, Luxury Room) 3. Traceback, as we try to get the availabilities on a negative period. start date > end date, as both dates are equals and the time is set from the Pickup and Return fields. Forward-Port-Of: odoo/enterprise#119480
Code cleanup and technical improvements
This update simplifies how plugins manage submit buttons within Odoo. Previously, a single, hardcoded list required developers to modify core code for each plugin. Now, plugins can easily register their own submit button selectors, making updates and maintenance much easier and more flexible. This improves the overall stability and maintainability of the Odoo platform.
Original PR description
\* = website, website_payment Previously submit button selectors were defined in a single hardcoded string in the save snippet logic. This made the list harder to maintain and required modifying the base code whenever a new plugin needed to exclude its submit button from being saved as a snippet. Introduce a resource allowing plugins to register their own submit button selectors. Plugins can now extend this list directly from their code without modifying the base implementation. This makes the logic easier to maintain and provides a reusable extension point for other submit-button related behaviors in plugins. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266991 Forward-Port-Of: odoo/odoo#252679
13 changes
Resolved issues and error corrections
This update fixes a bug that prevented payroll calculations from correctly generating worked day lines for employees using attendance-based work schedules. The change ensures that all employees, regardless of their flexible working arrangement, receive accurate wage calculations based on their attendance records. This improves payroll accuracy and reporting.
Original PR description
### **Steps to reproduce:** - Install Payroll and Attendance apps. - Create an employee with a flexible working schedule and work entry source as attendance. - Create an attendance record for this…
### **Steps to reproduce:** - Install Payroll and Attendance apps. - Create an employee with a flexible working schedule and work entry source as attendance. - Create an attendance record for this employee. - Create and compute a payslip for this employee. ### **Observed Behavior:** Worked Day lines are not generated, and Basic Wage is calculated as 0. ### **Expected Behavior:** Worked Day lines should be populated based on attendance records. ### **Root Cause:** During payslip computation, [_compute_worked_days_line_ids](https://github.com/odoo/enterprise/blob/4339010eb1e1633a67573d08e032f3922b0bec49/hr_payroll/models/hr_payslip.py#L1846) only generated work entries for versions having a `resource_calendar_id` at [1]. As a result, fully flexible employees without a working schedule were excluded from work entry generation, preventing worked day lines from being computed. [1]- https://github.com/odoo/enterprise/blob/4339010eb1e1633a67573d08e032f3922b0bec49/hr_payroll/models/hr_payslip.py#L1890-L1898 ### **Fix:** Remove the `resource_calendar_id` filter when calling `generate_work_entries` in `_compute_worked_days_line_ids` so work entries are also generated for fully flexible employees using attendance-based work entries. **opw-6146452**
This update corrects a technical error that prevented email notifications from being sent correctly within the planning module. The fix ensures that email actions function consistently across Odoo Enterprise, opening the standard email composer for sending messages. This resolves a minor disruption to workflow.
Original PR description
the used action name for the Send Email action was false its supposed to be action_send and not action_send_email task: 6244506
This update resolves a payment issue that occurred in self-order mode within the Viva POS system. The previous change introduced an error because a required method wasn't available in self-order. This fix simply adds a fallback mechanism to ensure payments continue to process correctly.
Original PR description
The PR odoo/odoo#267280 changed the Viva class to use the `getCashier` method to determine the `cashRegisterId`, however this method does not exist in self order, so an error is always thrown. This commit fixes the issue by simply adding a `?` so that it falls back to the POS config name. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268548
This update corrects an issue in the l10n_lu_reports module that caused incorrect balance sheet reports. Specifically, fields 2955 and 2956 must always be set to zero, as required by Luxembourg's eCDF reporting standards. Fixing this ensures reports are accepted by the eCDF, preventing rejection and guaranteeing accurate financial reporting.
Original PR description
Before this commit, fields 2955 and 2956 in the balance sheet could be incorrect. 2955 must always be blank (not exist) and 2956 must always be 0 per: https://ecdf-developer.b2g.etat.lu/ecdf/forms/popup/CA_PLANCOMPTA/2020/en/2/rules page 116 + 117 If they are not these values specifically, submitting the XML to eCDF results in the report being rejected. Steps to reproduce: - Install l10n_lu_reports - Create a journal entry for a closed year (2025) that debits account 142000 and credits another account that starts with a 1 - Go to the balance sheet for 2025 - Download the XML for the report - 2955 is present and 2956 is either not present or is not 0 (behavior varies between versions) Ticket [link](https://www.odoo.com/odoo/project.task/6246564) opw-6246564 Forward-Port-Of: odoo/enterprise#119193
This update corrects a technical issue where archived delivery carrier records were being unintentionally passed through the system. This prevented users from selecting the correct carriers when creating orders. By ensuring only active carriers are used in the context, this fix improves order processing accuracy and reliability.
Original PR description
Issue: property_delivery_carrier_id on res.partner can hold an archived delivery.carrier record. Meaning that we pass an archived record to the context and that we can select the archievd delivery.carrier in the choose.delivery.carrier wizard. Solution: Only pass active records through the context. opw-6125792 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264945 Forward-Port-Of: odoo/odoo#263819
This update resolves a previous issue that prevented users from successfully exporting records with properties from kanban and list views. Now, records containing properties can be exported to spreadsheets and exported data dialogs, ensuring a more complete and reliable data export process. This enhancement simplifies data analysis and reporting.
Original PR description
**Before this commit:** - Exporting records with properties from the kanban view caused a `Client Error`. - Inserting records with properties from the kanban view into a spreadsheet caused a `Client Error`. - Individual properties were not exported by default in list views (even when optionally displayed) or in kanban views. **After this commit:** - Records containing properties can be exported from the kanban view. - Records with properties can be inserted into a spreadsheet without errors. - Individual properties that are optionally displayed are listed by default in `Fields to Export`. enterprise: https://github.com/odoo/enterprise/pull/118913 task-6123524 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264267
This update ensures that all relevant data, including sub-properties, is now included when records are inserted into spreadsheets. This change aligns the spreadsheet export with other views (kanban, list) and improves data consistency across Odoo.
Original PR description
* = [documents_spreadsheet] Since `Insert in Spreadsheet` already supports sub-properties from saas-19.2 onwards, this change aligns the export behavior across kanban, list, and spreadsheet views by including sub-properties in the exported record data. community: https://github.com/odoo/odoo/pull/264267 task-6123524 Forward-Port-Of: odoo/enterprise#118913
This update fixes a technical error that was preventing warning messages from being logged correctly in the IoT module. The issue stemmed from how data was being passed to the logging function, and this change ensures that warnings are now consistently recorded without errors.
Original PR description
Error: ``` TypeError: Logger._log() got an unexpected keyword argument 'ip' ``` Cause: - The `**new_iot_record` unpacks the dictionary into keyword arguments for `Logger._log()` instead of supplying it as the value for the third `%s` placeholder in the warning message, causing the error because `_log()` doesn't accept keywords such as `version` or `ip`. sentry-7522168864 Forward-Port-Of: odoo/enterprise#119494
This update resolves a technical issue that was causing errors in the POS HR module, specifically related to how session information was accessed. By using the standard session ID instead of a backend-calculated field, the system is now more reliable and less prone to errors. This ensures smoother operation for users.
Original PR description
`pos.config.current_session_id` is a computed field from the backend. In some cases, it's possible that we don't have this field causing the following error
```
TypeError: undefined is not an object
(evaluating 'this.config.current_session_id.id')
```
task: https://www.odoo.com/odoo/project/1737/tasks/6253422
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#267225
Forward-Port-Of: odoo/odoo#266858This update resolves an issue where activity labels in the Chatter interface weren't displaying correctly when the default summary was removed. The fix ensures that activity labels now consistently use the 'display_name' when the summary is empty, providing accurate and consistent information for users. This improves the overall usability of the Chatter feature.
Original PR description
Before this commit: --- - Chatter activity display used [`summary`](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/static/src/core/web/activity.js#L42) to get…
Before this commit: --- - Chatter activity display used [`summary`](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/static/src/core/web/activity.js#L42) to get the display name. - If `summary` was empty, it fell back to [`display_name`](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/static/src/core/web/activity.js#L44). - However, `_to_store` only [stored](https://github.com/odoo/odoo/blob/4ba8950c25452cfe3310d40c26bd359c27f6c576/addons/mail/models/mail_activity.py#L680) `summary`. - As a result, nothing was shown when `summary` was empty, even though `display_name` was set. Steps to reproduce: --- - Create an activity in chatter - Remove the default summary if set. - Observer the title. https://github.com/user-attachments/assets/1684feb7-02d0-4ac1-9c00-d2aaae88e045 After this commit: --- - Added `display_name` to `_to_store` along with `summary`. - Chatter activity now correctly falls back to `display_name`. - Users can now see the correct activity label in chatter. OPW: 6212976 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267555 Forward-Port-Of: odoo/odoo#266706
This pull request addresses a technical issue within the HR module related to how contract version overlaps were calculated. The fix ensures more accurate reporting and prevents potential errors in version management, particularly concerning employee contracts. This improves the reliability of HR data.
This update resolves an issue where the Balance Sheet report's XLSX export was incorrectly including all accounts instead of just the selected ones when using the date filter. The fix removes a filtering step that was unintentionally introduced, ensuring the report accurately reflects the user's date selection criteria.
Original PR description
Steps: - Open Balance Sheet report and unfold lines - Open the General Ledger from a line with an account - On GL report, change date filter - Export XLSX report -> We export all accounts instead of the one selected in the search bar Cause: Since f8dceec74e44ffe4aef67655be8811c96da91eba we filter out the filter if a default account is defined in the context which is the case in the `caret_option_open_general_ledger` method Fix: Remove the filtering as the behavior that was fixed by the mentioned commit does not happen anymore. opw-6234427 Forward-Port-Of: odoo/enterprise#119547 Forward-Port-Of: odoo/enterprise#119156
This update resolves a problem where users attempting to access archived documents through specific methods (like widgets or direct URLs) would incorrectly display a 'not found' message. This fix ensures that archived documents are correctly accessed, improving the user experience and preventing frustrating errors. It's a follow-up to previous related tasks.
Original PR description
When a user tries to access an archived document via * a many2one widget * `/odoo/documents.document/<id>` * a discuss notification they end up in "All" with a toast specifying that the document was not found. Follow-up of Task-6068437 (follow up of Task-5386466). Task-6214488 Forward-Port-Of: odoo/enterprise#119463 Forward-Port-Of: odoo/enterprise#117229
13 changes
Enhancements to existing features
This update allows customers using the self-order system to pay at the counter, even if they've already selected a payment method within the self-order interface. This provides greater flexibility for customers and streamlines the checkout process, particularly in scenarios where a customer wants to combine self-order with counter payment options. It improves the overall customer experience.
Original PR description
pos*: point_of_sale, pos_self_order This commit allows the user to allow his customer to pay at the counter even if they already have payment method set in the self order. task-id: 5960666 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This update corrects a bug in how overtime calculations are handled across multiple days, specifically when an attendance crosses into a non-working day. The fix prevents overlapping overtime intervals caused by rounding errors, ensuring accurate overtime tracking. This improves the reliability of employee time reporting.
Original PR description
**Problem:** When an attendance has overtimes across multiple days, those overtimes can overlap when calculating their intervals. There will always be rounding errors since only the durations are…
**Problem:** When an attendance has overtimes across multiple days, those overtimes can overlap when calculating their intervals. There will always be rounding errors since only the durations are saved to 3 decimals, but this is normally fine since the durations are accumulated when calculating the next interval. However, on a day boundary in the employee timezone, the end of the interval is forced to the end of day, which incidentally removes the rounding error. This causes the overlap when calculating the next interval since its start will be based on the rounded duration, not the actual end of day. **Steps to Reproduce:** - Configure an overtime rule where >8 hours is considered overtime, and a second rule applies to non-working days - Set Overtime Rule on employee "Anita Oliver" - Set employee work entry source to "Attendances" - Create an attendance that exceeds 8 hours in a day and crosses into a non-working day and creates enough of a rounding error (see unit test) -> Traceback error: `ValueError: Expected singleton: hr.attendance.overtime.line(1, 2)` **Solution:** Add an additional check to ensure the overtime cannot start on the previous day. opw-6067969 Forward-Port-Of: odoo/enterprise#118570
A technical issue preventing users from accessing billing targets within the timesheet feature has been resolved. This fix ensures a smoother workflow for employees and managers managing billable time. The change addresses a problem related to a required field within the timesheet configuration.
Original PR description
… of employees Prerequisites to reproduce: - Enable `Billing Rate Indicators` in timesheets. - Change timesheet access of user to `User: all timesheets` - Remove Employee access Steps to Reproduce: - In Timesheets app, from configuration go to `Billing Time Targets` - Click on view button on any row Issue: - A traceback breaking the flow. Reason: - We use `hr_presence_status` widget which requires `work_location_type` field, change made from https://github.com/odoo/odoo/commit/0496ed10636c7b2dfde7038a43494d4edbd9f95b. - Thus unavailability of field causing the traceback. Fix: - Add a related field for work_location_type from which we get the value. Forward-Port-Of: odoo/enterprise#97502
This update corrects an issue in the l10n_lu_reports module that caused incorrect balance sheet reports due to incorrect data in XML fields. Specifically, fields 2955 and 2956 must always be set to zero, as required by Luxembourg's eCDF reporting standards. Fixing this ensures reports are accepted by the tax authority, preventing rejection and potential compliance problems.
Original PR description
Before this commit, fields 2955 and 2956 in the balance sheet could be incorrect. 2955 must always be blank (not exist) and 2956 must always be 0 per: https://ecdf-developer.b2g.etat.lu/ecdf/forms/popup/CA_PLANCOMPTA/2020/en/2/rules page 116 + 117 If they are not these values specifically, submitting the XML to eCDF results in the report being rejected. Steps to reproduce: - Install l10n_lu_reports - Create a journal entry for a closed year (2025) that debits account 142000 and credits another account that starts with a 1 - Go to the balance sheet for 2025 - Download the XML for the report - 2955 is present and 2956 is either not present or is not 0 (behavior varies between versions) Ticket [link](https://www.odoo.com/odoo/project.task/6246564) opw-6246564 Forward-Port-Of: odoo/enterprise#119193
This update corrects a technical issue where archived delivery carriers were being unintentionally included in the carrier selection process. Previously, the system would pass information about inactive carriers, leading to incorrect choices in the delivery wizard. This change ensures that only active carriers are considered, improving the accuracy and reliability of delivery options.
Original PR description
Issue: property_delivery_carrier_id on res.partner can hold an archived delivery.carrier record. Meaning that we pass an archived record to the context and that we can select the archievd delivery.carrier in the choose.delivery.carrier wizard. Solution: Only pass active records through the context. opw-6125792 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264945 Forward-Port-Of: odoo/odoo#263819
This update ensures receipts can now be prepared and printed offline, regardless of whether the order was synced. Previously, syncing orders caused errors, preventing offline receipt generation. This change improves the user experience by allowing for offline operations without disruption.
Original PR description
Preparation receipts could be printed offline only if the order was not synced. If orders were synced, the `ConnectionLostError` were preventing the call to be executed. Forward-Port-Of: odoo/odoo#268570
This update corrects a bug where French users were seeing English versions of audit reports. The fix ensures that all generated reports, like the annual report, are correctly translated into French based on user language preferences. This improves the user experience for French-speaking customers.
Original PR description
This commit is linked to this one: 8209f4ff098afc8b447074b6d2cae389c6b52c7c that was retarget to master (at that time was saas-19.3). ### Steps to reproduce the issue: 1. Download Accounting and accountant_knowledge (audit reports) 2. Switch to French language in user preferences 3. Go to Rapport Annuel 4. Create a new one and print it 5. See it's not in french but in english opw-6219866
This update fixes an issue where the 'Cancel Reason' wasn't being properly transmitted when reversing invoices in Peruvian companies. Now, the credit note generated after reversing includes the user-specified cancellation reason, ensuring accurate reporting to the Peruvian tax authority (SUNAT) and compliance with local regulations. This improves data accuracy and reduces potential errors.
Original PR description
### Issue before this commit: When reversing an invoice in a Peruvian company, the "Cancel Reason" entered in the credit note window is not propagated to the Peruvian EDI tab of the resulting Credit…
### Issue before this commit: When reversing an invoice in a Peruvian company, the "Cancel Reason" entered in the credit note window is not propagated to the Peruvian EDI tab of the resulting Credit Note. Only the Credit Reason is successfully reported. ### Steps to reproduce the issue: 1. Download Accounting and l10n_pe 2. Switch to PE company 3. Create an invoice and confirm it 4. Create a credit note for the invoice with a cancel reason and a credit reason and click the reverse button 5. See that in the Peruvian EDI tab only the Credit Reason is reported but not the Cancel Reason ### Cause of the issue: In the l10n_pe_edi module, the override of the _prepare_default_reversal method maps the l10n_pe_edi_refund_reason to the new move's values, but completely omits the mapping of the wizard's textual reason field to the l10n_pe_edi_cancel_reason field of the resulting credit note. ### Reason to introduce the fix: To ensure the generated credit notes contain all required information for the Peruvian EDI (SUNAT). Mapping the cancel reason guarantees that the electronic document accurately reflects both the refund code and the descriptive cancellation text provided by the user. opw-6238525 Forward-Port-Of: odoo/enterprise#119532 Forward-Port-Of: odoo/enterprise#118479
This update fixes an issue where order confirmation emails weren't sent to customers when using Automatic Invoice. The change ensures that email confirmations are sent correctly, even when partners don't have a user account, improving the customer experience and order tracking. This was triggered by a recent update to invoice automation.
Original PR description
With Automatic Invoice enabled, no mail confirmation is sent when a picking is validated and the partner doesn't have a user Steps to reproduce: 1. Install eCommerce and Sales 2. Go to Settings >…
With Automatic Invoice enabled, no mail confirmation is sent when a picking is validated and the partner doesn't have a user Steps to reproduce: 1. Install eCommerce and Sales 2. Go to Settings > Inventory > Shipping and enable "Email Confirmation" 3. Go to Settings > Sales > Invoicing and enable "Automatic Invoice" 4. Go to Website > Configuration > Payment Providers and Install Demo 5. Go to Sales > Products, open product "Office Lamp", click on "Update Quantity" in the status bar and add 5 units 6. Log out 7. Go to the shop, add product "Office Lamp" to the cart and checkout 8. Fill in the address form and continue checkout 9. Confirm the order and pay with Demo 10. As user Mitchell Admin, go to Sales, remove the default filter and open the newly created sale order 11. Open the related delivery with the smart button and validate it 12. No delivery order confirmation was sent to the customer (check emails) Issue: When automatic_invoice is enabled, we automatically send an invoice when the payment transaction of an order has been processed. This has the effect of archiving partners that don't have a user https://github.com/odoo/odoo/blob/fa9c16472939f71ff9687718f25addd64bb1a97c/addons/website_sale/models/payment_transaction.py#L9-L14 Solution: ??? opw-6232937
This update automatically populates expense descriptions using the names of uploaded receipts. Previously, expenses created from receipts lacked descriptions, making it difficult to track them. This change simplifies expense identification and reporting, especially when multiple receipts are uploaded.
Original PR description
When creating expenses from uploaded receipts, the generated expense description wasn't set. This made it hard to identify expenses after uploading several receipts at once. Use the uploaded document name as the default expense description instead. task-6272164 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where sale order prices were incorrectly displayed in invoicing reports. The change ensures that the price shown reflects the actual price set on the sale order line, rather than the product's base price. This improves the accuracy of financial reporting and invoicing.
Original PR description
Steps to reproduce: - - Create a Sale Order with two sale order lines for the same product. - Set different prices on each SOL (e.g. 20 and 40). - Open the related project and go to the Invoicing tab. - Search for the Sale Order Lines. Issue: - Displayed price uses the product price instead of the SOL price. Cause: - The display name formatting used `product_id.lst_price`. Solution: - Use `price_unit` from the sale order line to show the correct price. task-5966799
This update prevents kiosk orders from being sent to the blackbox system unless payment is confirmed. This change ensures that orders processed at the counter with various payment methods are correctly handled, streamlining the order flow and improving the kiosk experience. It addresses a potential issue where unpaid orders were incorrectly routed.
Original PR description
This commits adapts the code in confirmation_page.js to not send the order to the blackbox from the kiosk if the order is not in paid state. task-id: 5960666
This update fixes an issue where the ICP export generated inconsistent XML reports by pulling data from multiple company contexts. The change ensures a single, reliable company context is used, reusing precomputed values and preventing unintended overwrites. This results in more accurate and understandable ICP export data.
Original PR description
Description of the issue this commit addresses: The ICP export could mix values from different company contexts. In some cases, the main identifier and the fiscal entity division value did not come from the same source, which could create confusing or inconsistent XML output. --- Desired behavior after this commit is merged: This commit makes the ICP export use one consistent company context for identifier values, reuses precomputed values when available, and avoids overwriting them with unrelated defaults. --- task-6065382 Forward-Port-Of: odoo/enterprise#119455 Forward-Port-Of: odoo/enterprise#112995
2 changes
Resolved issues and error corrections
This update corrects an issue in the l10n_lu_reports module that caused incorrect balance sheet reports due to incorrect XML data. Specifically, fields 2955 and 2956 must always be set to zero, as dictated by Luxembourg tax regulations. This change ensures reports are accepted by the eCDF system, preventing rejection and maintaining accurate financial reporting.
Original PR description
Before this commit, fields 2955 and 2956 in the balance sheet could be incorrect. 2955 must always be blank (not exist) and 2956 must always be 0 per: https://ecdf-developer.b2g.etat.lu/ecdf/forms/popup/CA_PLANCOMPTA/2020/en/2/rules page 116 + 117 If they are not these values specifically, submitting the XML to eCDF results in the report being rejected. Steps to reproduce: - Install l10n_lu_reports - Create a journal entry for a closed year (2025) that debits account 142000 and credits another account that starts with a 1 - Go to the balance sheet for 2025 - Download the XML for the report - 2955 is present and 2956 is either not present or is not 0 (behavior varies between versions) Ticket [link](https://www.odoo.com/odoo/project.task/6246564) opw-6246564 Forward-Port-Of: odoo/enterprise#119193
This update simplifies how spreadsheet documents are managed within Odoo, reducing unnecessary data and improving performance. By disabling versioning for spreadsheets and frozen spreadsheets, we prevent duplicate history and document creation. This change ensures a smoother and more efficient experience for users working with these file types.
Original PR description
Spreadsheet documents already manage their own history through spreadsheet revisions. Running generic Documents versioning on top of that creates unnecessary history attachments and additional documents when spreadsheet data is written or when a spreadsheet is copied. Keep the default Documents versioning behavior for regular documents, but allow spreadsheet and frozen spreadsheet documents to opt out of Documents versioning. Also hide the Manage Versions action for those records. This PR combines: * a backport of enterprise commit 0e319d063ae868d6e48e9fd6741caf5156308eae disabling Documents versioning for spreadsheets; * a follow-up change hiding the Manage Versions action for spreadsheet records. Task: 6236496 Forward-Port-Of: odoo/enterprise#118484
5 changes
Resolved issues and error corrections
This update fixes a bug where credit limit warnings were incorrectly triggered by bank payments. Now, the system accurately considers outstanding bank payments when calculating a customer's outstanding balance, ensuring warnings only appear when limits are genuinely exceeded. This improves the accuracy of credit risk management.
Original PR description
Before this fix: The credit limit warning calculation only considered credit notes but ignored outstanding bank payments when computing the partner's effective outstanding balance. For example, if a…
Before this fix: The credit limit warning calculation only considered credit notes but ignored outstanding bank payments when computing the partner's effective outstanding balance. For example, if a customer had a credit limit of 1,000 and an invoice of 2,000 was created, then a bank payment of 1,500 was received, the warning would still incorrectly appear showing the customer exceeded their limit (2,000 > 1,000), even though the actual outstanding amount was only 500. After this fix: The credit limit warning now properly includes outstanding bank payments in the calculation. Two cases are handled: - Bank payments received but not yet matched to any invoice, these are identified by their open suspense account entry and deducted from the partner's outstanding exposure. - Bank payments already matched to the invoice, the reconciled amount is read from the invoice's receivable line and deducted accordingly. So with this fix, after a 1,500 bank payment, the system correctly recognises the outstanding amount as 500 and does not show a warning since it is within the 1,000 credit limit. task-5427613
This update fixes an issue where DATEV exports incorrectly populated fields for customers outside the European Union. Now, the correct country code (`Land`) is automatically filled for non-EU customers, ensuring accurate reporting and compliance with DATEV's data format requirements. This ensures data consistency and avoids errors in financial reports.
Original PR description
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries…
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries For non-EU countries, the `Land` field should be filled instead, and is required whenever the country is not Germany https://developer.datev.de/en/file-format/details/datev-format/format-description/debitorskreditors ### Cause: `_l10n_de_datev_get_partner_list` did not distinguish between EU and non-EU countries As a result, any partner with a VAT number could populate `EU-Land` and `EU-UStID`, even if the country was outside the EU Greece also requires a special case: its VAT prefix is `EL` so the `EU-Land` too, while the country code used in `Land` must remain `GR` ### Steps to reproduce: - Install `l10n_de_reports` and switch to the DE company - Create a customer in Switzerland with a valid VAT number - Create and confirm an invoice for that customer - Go to Accounting → Audit Reports → General Ledger - Select the full year - From the gear menu, export DATEV DATA (zip) - Open the `EXTF_customer_accounts` file ### Before the fix: `EU-Land` and `EU-UStID` are filled for the Swiss customer, while `Land` is empty ### After the fix: `EU-Land` and `EU-UStID` are empty for non-EU countries such as Switzerland, while `Land` is correctly filled `Land` is filled using the following priority: 1. Partner country_code 2. Country extracted from the VAT number 3. Empty opw-5902565 Forward-Port-Of: odoo/enterprise#113835
This update significantly speeds up the process of checking if a field can be deleted within website forms. Previously, this check took several minutes, causing delays. Now, it completes in just milliseconds by focusing only on the HTML fields that actually need to be validated, dramatically improving user experience.
Original PR description
Summary ======= `_check_if_used_in_website_form`, the ondelete hook on `ir.model.fields` that guards against deleting a field referenced by a website form, performs poorly on realistic databases. It…
Summary
=======
`_check_if_used_in_website_form`, the ondelete hook on
`ir.model.fields` that guards against deleting a field referenced by
a website form, performs poorly on realistic databases. It can take
multiple minutes to validate a single field deletion, blocking user
actions such as removing a Studio field.
This commit restricts the scan to columns that can actually contain
website form markup, bringing the hook from multi-minute to
sub-second without any loss of coverage.
The Problem
===========
Deleting any `ir.model.fields` record triggers this validation hook,
which must ensure the field is not referenced inside any website
form. The implementation iterates every stored HTML column returned
by `website._get_html_fields()` and runs one case-insensitive
`ILIKE '%data-model_name="<model>"%'` search per column against
`<model>.<html_field>`, then parses each match with `lxml` and
validates it with XPath.
Two root issues cause the multi-minute cost:
- **Unbounded scan surface**: all stored HTML columns are scanned
(~95 on realistic databases), even though the vast majority of them
declare `sanitize=True` and `sanitize_form=True` (the defaults).
When both flags are True, `<form>` tags are stripped on write and
the column can never physically contain website form markup.
- **Per-column `ILIKE` cost**: `ILIKE` on large TEXT/JSONB columns
performs a sequential scan. A single large HTML column is enough
to make the hook run for several minutes on its own.
Improvements
============
- Scan only columns that can actually contain forms:
- `ir.ui.view.arch_db` , primary target; all website forms are
stored there.
- HTML fields whose sanitization either is disabled
(`sanitize=False`, e.g. `blog.post.content`,
`website.custom_code_head`) or explicitly allows forms
(`sanitize_form=False`, e.g.
`product.template.website_description`, `hr.job.description`,
`event.event.description`). Any other HTML field strips `<form>`
on write and will never contain a form.
- Batch searches: group the deleted fields by model once and emit a
single `OR`-domain search per candidate column, instead of one
search per (field, column) pair.
- Parse each returned record with `lxml` and validate with XPath
directly. The `ILIKE` domain already filters out non-matching rows
DB-side.
Benchmarks
==========
Profiled on a database containing ~95 stored HTML columns and ~5.2k
views. The hook was invoked read-only via
`field._check_if_used_in_website_form()` on a custom field.
| Metric | Before | After |
| :----------------------------- | ---------: | ---------: |
| Hook wall time | ~444 s | ~173 ms |
| HTML columns scanned | 95 | 5 |
| SQL queries issued | 96 | 6 |
Key results:
- Hook wall time reduced from multi-minute to sub-second
(~2,570× faster on the profiled database).
- Scan surface reduced from ~95 columns to a handful (1 +
the form-capable HTML fields installed on the database, typically
under 10).
opw-6086536
Forward-Port-Of: odoo/odoo#259846This update resolves an issue where the barcode inventory count feature would fail when using archived units of measure. The fix ensures that archived UOMs are correctly included in the inventory count cache, allowing accurate counts to be performed. This prevents errors during physical inventory adjustments.
Original PR description
### Steps to reproduce: - In the settings enable: "Units of Measure & Packagings", "Storage Locations" - Create a product in units and register 1 unit in stock - Inventory > Operations > Adjustments…
### Steps to reproduce: - In the settings enable: "Units of Measure & Packagings", "Storage Locations" - Create a product in units and register 1 unit in stock - Inventory > Operations > Adjustments > Physical Inventory - Select your line and request a count > Set Current Value - Inventory > Configurations > units of measures > UOM categories - Select unit and archive it - Go to the barcode app > Click Count inventory ### > Owl error: Uncaught promise ### Cause of the issue: Since the uom used on the quant is archived, it is not found by the search used to fill the barcodeCache: https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/models/stock_quant.py#L104-L106 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/models/barcode_model.js#L37-L39 However, if the uom is not present in the barcode cache the `BarcodeQautnModel` will fail to createLinesState whihc raises a missing error: https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/models/barcode_quant_model.js#L712 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/lazy_barcode_cache.js#L107-L110 opw-6250090 Forward-Port-Of: odoo/enterprise#118877 Forward-Port-Of: odoo/enterprise#118813
This update prevents the checkout page from repeatedly reloading when discounts are applied to products with different tax configurations. The change ensures discount lines are correctly grouped, resolving a synchronization issue between the backend and frontend, and improving the user's checkout experience.
Original PR description
**Step to reproduce :** 1. Create a deliverable product with a sales tax. 2. Create another product with a different sales tax. 3. Publish both products on the eCommerce website. 4. Create a discount…
**Step to reproduce :**
1. Create a deliverable product with a sales tax.
2. Create another product with a different sales tax.
3. Publish both products on the eCommerce website.
4. Create a discount program.
5. Add both products to the shopping cart.
6. Apply the discount code.
7. Proceed to checkout.
**Issue :**
Applying a discount on multiple products with different taxes causes an infinite reload cycle during checkout.
**Reason :**
The reload is supposed to sync the discount lines in the back-end with the discount lines displayed during checkout. If the number of lines don't match, a reload is triggered.
https://github.com/odoo/odoo/blob/18.0/addons/website_sale_loyalty/static/src/js/checkout.js#L22-L24
After the fix introduced in:
https://github.com/odoo/odoo/pull/248215
However, when a discount is applied to products with different taxes, the corresponding reward lines are still categorized as `discounted_lines` instead of `groupable_lines`. As a result, they continue to be processed individually rather than being grouped by reward.
This leads to a mismatch between the backend, which generates one discount line per tax combination, and the frontend, which expects a single discount entry per reward. Consequently, the checkout page continuously reloads while attempting to synchronize both states.
**Solution:**
When a discount applies to products with different tax configurations, the corresponding reward lines should be included in `groupable_lines` rather than `discounted_lines`. This ensures that discount lines are grouped by
`reward_id` consistently on both the frontend and backend, preventing the checkout reload loop.
opw-6210411
Forward-Port-Of: odoo/odoo#2657404 changes
Resolved issues and error corrections
This update resolves an issue where the commission report displayed empty groups for inactive commission plans. By filtering out these plans during the report generation, the report now shows only relevant, populated data, improving the accuracy and clarity of sales performance insights. This ensures sales teams see the most up-to-date commission information.
Original PR description
Steps to reproduce: 1. create a commission plan 2. invoice an SO with the linked salesperson to the plan to progress towards the target 3. Archive the commission plan 4. Go to Sales > Commissions > Commissions 5. Remove all filters The `sale.commission.report` includes empty groups for `sale.commission.achievement.report` that are linked to inactive commission plans By excluding said plans from the initial join, the report would display populated groups only without the clutter. opw-6177132 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue that prevented successful testing of duplicated databases for the l10n_de_pos_cert module. Specifically, the commit removes `client_id` and `tss_id` during database duplication, allowing for proper testing in neutralized environments. This ensures consistent and reliable testing of the German POS certification functionality.
Original PR description
In this commit: -------------------- - On a duplicate database `client_id` and `tss_id` are removed so it works as test in neutralized dbs without throwing errors. task- 5457231 Forward-Port-Of: odoo/enterprise#104119
This update corrects an issue in the l10n_lu_reports module where the balance sheet XML reports were incorrectly generating data. Specifically, fields 2955 and 2956 needed to be set to a fixed value (zero) to comply with Luxembourg tax regulations and avoid report rejection by the eCDF system. This ensures accurate financial reporting for Luxembourg businesses.
Original PR description
Before this commit, fields 2955 and 2956 in the balance sheet could be incorrect. 2955 must always be blank (not exist) and 2956 must always be 0 per: https://ecdf-developer.b2g.etat.lu/ecdf/forms/popup/CA_PLANCOMPTA/2020/en/2/rules page 116 + 117 If they are not these values specifically, submitting the XML to eCDF results in the report being rejected. Steps to reproduce: - Install l10n_lu_reports - Create a journal entry for a closed year (2025) that debits account 142000 and credits another account that starts with a 1 - Go to the balance sheet for 2025 - Download the XML for the report - 2955 is present and 2956 is either not present or is not 0 (behavior varies between versions) Ticket [link](https://www.odoo.com/odoo/project.task/6246564) opw-6246564 Forward-Port-Of: odoo/enterprise#119193
This update fixes an issue where DATEV exports incorrectly populated EU-specific fields for customers outside the European Union. The change ensures that the correct country information is used, aligning with DATEV's data format requirements and improving data accuracy for reporting. This ensures compliance and accurate reporting for all customers.
Original PR description
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries…
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries For non-EU countries, the `Land` field should be filled instead, and is required whenever the country is not Germany https://developer.datev.de/en/file-format/details/datev-format/format-description/debitorskreditors ### Cause: `_l10n_de_datev_get_partner_list` did not distinguish between EU and non-EU countries As a result, any partner with a VAT number could populate `EU-Land` and `EU-UStID`, even if the country was outside the EU Greece also requires a special case: its VAT prefix is `EL` so the `EU-Land` too, while the country code used in `Land` must remain `GR` ### Steps to reproduce: - Install `l10n_de_reports` and switch to the DE company - Create a customer in Switzerland with a valid VAT number - Create and confirm an invoice for that customer - Go to Accounting → Audit Reports → General Ledger - Select the full year - From the gear menu, export DATEV DATA (zip) - Open the `EXTF_customer_accounts` file ### Before the fix: `EU-Land` and `EU-UStID` are filled for the Swiss customer, while `Land` is empty ### After the fix: `EU-Land` and `EU-UStID` are empty for non-EU countries such as Switzerland, while `Land` is correctly filled `Land` is filled using the following priority: 1. Partner country_code 2. Country extracted from the VAT number 3. Empty opw-5902565 Forward-Port-Of: odoo/enterprise#113835
8 changes
New functionality added to Odoo
This update adds visually engaging, themed banners to the Odoo Enterprise dashboard warning list. These banners change monthly to provide a more user-friendly and informative experience for employees. The change improves the overall look and feel of the dashboard.
Original PR description
This commit adds a playful thematic banner for each month in the dashboard warning list. task-6074778 <img width="1216" height="931" alt="Screenshot 2026-04-24 at 17 52 38" src="https://github.com/user-attachments/assets/1203cd33-b400-4e40-8cca-941bcce7341c" />
Enhancements to existing features
This update simplifies the selection of employee types within the Belgian payroll system. The 'Worker' employee type is now the second option after 'Employee' in the employee type list, making it easier for users to find and select. This change improves usability and streamlines the payroll process for Belgian businesses.
Original PR description
Update sequence order for employee type in Belgium, move worker as the second options after employee in Employee Type, makes users easier to find it task:6280177
This update enhances the user experience when creating new folders within the Documents module. Now, users can directly enter a custom folder name instead of accepting the default 'New Folder' name, making the process more intuitive and flexible. This change improves usability and streamlines folder creation.
Original PR description
**Specifications:** When clicking the '+' icon to create a new folder, open a dialog box, that allow the user to enter a folder name instead of using the default name: 'New Folder'. Task-6147707
This update enhances the employee experience by automatically filtering payslips within the view, grouping them by year and expanding the view for easier access. This simplifies payslip retrieval and provides a more organized view for employees.
Original PR description
This will add default filter when accessing payslip view from employee using smartbutton, the filter will group the payslip by date_from year and set the expand = True task:6237600
Resolved issues and error corrections
This update fixes an issue where portal users were redirected to the wrong folder when accessing documents. The fix ensures that links from the Documents section correctly navigate users to the intended folder, improving the user experience. This was caused by a technical oversight in updating folder references.
Original PR description
# How to reproduce - As admin, give access to folder X & folder Y to a portal user - As that portal user, go to Documents, click on folder X and copy the page url - Click on folder Y - Paste the URL in the browser's search bar # The problem You are still in folder Y, even though the link should be to folder X. # Cause We forgot to keep `documents_init`' s `folder_id` (refactored into `user_folder_id`) in https://github.com/odoo/odoo/commit/6bdcc357b195faa0aad8c05eac23aa0a762dd76b opw-6132231 Forward-Port-Of: odoo/enterprise#116928
This update enhances the accuracy of vendor credit note reporting within the Odoo Enterprise system. Specifically, the system now prioritizes using the 'bill reference' when generating reports for vendor credit notes, ensuring more reliable data. This change maintains the previous fallback behavior for compatibility.
Original PR description
With this commit, we update the report to prioritise the bill reference for vendor credit notes while keeping the previous fallback behaviour task-6235022
This update fixes a problem where payruns were incorrectly marked as cancelled after removing individual payslips. The change ensures payruns remain valid even after edits, preventing disruptions in payroll processing. This improves the reliability of payrun management.
Original PR description
Fixes the following bugs in payruns: BUG 1: - create a payrun, leave it in draft - create a single payslip, add it to the previously created payrun. The payslip employee will appear in the payrun employee list - for the previously created payslip, remove it from the payrun - go back to payruns kanban view, the payrun will results as cancelled even if there still were other employee entries in it (the one defined at start) BUG 2: - create a payrun, leave it in draft - create a single payslip, add it to the previously created payrun. The payslip employee will appear in the payrun employee list - go on the payrun and clicking on the button "Off-Cycle" for the separately-created payslip This adds other employees not originally on the payrun task: 6237460
This update resolves an issue preventing printing from the Odoo Mobile App. The fix addresses a conflict between how print requests were handled, allowing users to successfully print POS tickets directly from the app. This improves the mobile user experience.
Original PR description
This commit patches the `PosTicketPrinterService` to enable ticket printing in the Mobile App. Previously, printing did not work because the POS created a new `IFRAME` for each print operation, while the Mobile App patched `window.print` only once. In addition, older versions of the Mobile App did not support `IFRAME` printing.
8 changes
Resolved issues and error corrections
This update resolves a performance issue that caused the Budget Report to time out on large Odoo databases. The fix optimizes the underlying SQL query to handle complex budget data more efficiently, resulting in significantly faster report generation. This improves usability for users working with extensive financial data.
Original PR description
**Description** Opening the Budget Report from any budget record times out on databases with significant data volume. The request to `budget.report/formatted_read_grouping_sets` consistently times…
**Description**
Opening the Budget Report from any budget record times out on databases
with significant data volume. The request to
`budget.report/formatted_read_grouping_sets` consistently times out,
making the Budget Report completely unusable.
**Root cause:**
`budget.report` is an SQL view that consists of 5 UNION ALL branches.
When the list view loads, the ORM translates the `budget_analytic_id`
domain into a WHERE clause on the outer query wrapping the full UNION
ALL subquery. PostgreSQL cannot push this filter through a UNION ALL as
it's a hard optimization barrier. It must fully materialize the subquery
regardless of which budget is being viewed.
**Fix:**
Override _search on budget.report to extract budget_analytic_id and
budget_line_id conditions from the incoming domain using the Domain API.
budget_line_id is rewritten as Domain('id', op, value) so _to_sql()
correctly emits bl.id in the raw SQL. The resulting domain is injected
in context under budget_line_domain and read in _get_bl_query,
_get_aal_query (base module), and _get_pol_query (purchase module) to
filter budget_line rows inside each branch's LEFT JOIN ON clause.
This also removes the budget_report_budget_line_ids context key from
budget_line._compute_all, unifying both filters under one mechanism.
---
On customer DB (568k `account_analytic_line`, 27k `budget_line`,
116k confirmed `purchase_order_line`, 114k posted vendor bill lines
with purchase link):
| Budget | Before | After |
|---|---|---|
| 8 lines, 730d span | timeout | 2.27s |
| 14 lines | timeout | 2.39s |
| 14 lines, 1095d span | timeout | 1.63s |
- Before: https://explain.dalibo.com/plan/ehed5eb8de251426
- After: https://explain.dalibo.com/plan/db8aef35cag9hg6f
opw-6098047This update resolves an issue where the EC List XML export incorrectly treated invoices with the same VAT number as separate partners, leading to rejection by the Belgian tax agency. The fix ensures that invoices with identical VATs are grouped together in the XML, meeting regulatory requirements. This prevents errors and ensures accurate tax reporting.
Original PR description
With l10n_be: - Create two contacts with the same VAT - Create an invoice for each that is EC List compatible - Generate the return and export the EC List XML In the generated xml the two partners with the same vat are treated as different partners, which causes a rejection by the tax agency. opw-6109585
This update optimizes the way Odoo recalculates styles in large tables, like the Accounting > Balances Sheets. By removing unnecessary selectors, it reduces the time needed for these recalculations, leading to faster performance during scrolling, resizing, and sorting.
Original PR description
Adapt selector to remove the :has value since it not needed to have the effect applied. This reduces work during the "Recalculate Style" phase (for example when hovering rows in large tables such as the Accounting > Balances Sheets). It lowers recalculation time during window resizes, heavy scrolling, and table sorting by preventing broad selector matches and limiting style checks to elements with the specific class. This commit is a follow up of https://github.com/odoo-dev/enterprise/commit/8aa63b3c726d825e68430bb0a64a54c1b58d6af7 Note: We also fixes the scss button variable not correctly overided
This update resolves an issue where scanning a package type alongside a regular package didn't correctly link the new package to the product, preventing it from appearing in the inventory. The fix ensures that scanning a package type creates a new package and associates it with the correct product, improving the barcode scanning workflow.
Original PR description
When scanning a package then a package type, from the point of view of the user nothing happend, and in the backend it will created a new package but it will not link it to the products nor will it…
When scanning a package then a package type, from the point of view of the user nothing happend, and in the backend it will created a new package but it will not link it to the products nor will it show any warning. Steps to reproduce: ------------------- * Install barcode and stock * Enable packages in settings * Open Inventory * Create a product, * Create a Package Type -> barcode PACKTYPE, * Create a Package linked to this package type -> PACK, * Add at least 2 unit of product to this package, * Create a delivery for 2 unit of the product, Open Barcode * Operation > Delivery orders > your delivery * Erase the destination package from the first line * Scan PACK ( don't click on the green line) * Scan PACKTYPE **Actual behavior** create a new package but does not link it to the new products **Expected behavior** create a new package and set it as destination package. Observation: ------------- When scanning the package (PACK), we will go through ```_processPackage``` -> ```async _processPackage``` where in the end the line is unselected: https://github.com/odoo/enterprise/blob/39d8a473fe03038ca0494a6a8165e3eb75bd8492/stock_barcode/static/src/models/barcode_picking_model.js#L2090 When we scan our package type (PACKTYPE), we will go to ``` _processPackage``` -> ```_processPackage```->```_processPackageType``` where we will obtains packagesIds checking that we have a source package: https://github.com/odoo/enterprise/blob/7cd9834d1d918f12dec43844cae6f112309e5772/stock_barcode/static/src/models/barcode_picking_model.js#L2123-L2132 and will send us to ```_putPackInPack```: https://github.com/odoo/enterprise/blob/7cd9834d1d918f12dec43844cae6f112309e5772/stock_barcode/static/src/models/barcode_picking_model.js#L2133-L2136 Where we will avoid the empty packageIds since we checked on the source package and not the destination package: https://github.com/odoo/enterprise/blob/2b887d094c66be7aebd92fbf735b1852f5dde4b5/stock_barcode/static/src/models/barcode_picking_model.js#L2296-L2299 and will call ```action_put_in_pack``` from the packaging model: https://github.com/odoo/enterprise/blob/2b887d094c66be7aebd92fbf735b1852f5dde4b5/stock_barcode/static/src/models/barcode_picking_model.js#L2301-L2306 In ```action_put_in_pack``` will create a new packaging and put it as a the new destination package, but since the ```previous_dest_package``` (saved in db) was itself, he will [erase the link](https://github.com/odoo/odoo/blob/cda011dc8590773f6c3a26f4ae9d5242a3147024/addons/stock/models/stock_package.py#L354-L363) he just made. Which means that in our case, we created a package without linking it to anything. Even if we avoid the function to erase the destination package, since the destination package shown in barcode is the one from move line : https://github.com/odoo/enterprise/blob/d0d0a3cf4a02bf24cf502b533e494fe7ca155eb3/stock_barcode/static/src/components/line.js#L115-L117 It will not show the new package in barcode opw-5449729
This update resolves a critical issue preventing correct receipt printing in Austria by accurately calculating the closing receipt offset. It also addresses a deadlock during authentication with Fiskaly and FON, ensuring smoother and more reliable operation. This improves the user experience for Austrian POS users.
Original PR description
In this task: -------------- - Fixed Austria closing receipt printing by calculating the offset from the last closed month instead of the current month. Closing records are returned in ascending order and exist only for completed months, so the latest month must use offset 0. - Prevent a deadlock during Fiskaly and FON authentication by checking for open sessions before starting any authentication flow, instead of after the first step of authentication. - The resp was used to show error which was not in the scope. task: 5420256 Forward-Port-Of: odoo/enterprise#102313
This update fixes a bug that allowed internal transfer validations to proceed without scanning the destination location. Previously, deleting a line would cause validation to succeed even if the location hadn't been scanned. The fix ensures that validation is blocked until the destination location is properly scanned, improving data accuracy and preventing incorrect transfer processing.
Original PR description
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required.…
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required. ## Steps to produce: - Install the Inventory module - Go to Settings and enable Storage Locations. - Inventory > Configuration > Operation Types > Internal Transfers > Barcode App - Configure the Destination Location to require scanning after each product. - Create an Internal Transfer for Pedal Bin, demand 1. - Mark the transfer as To Do and open it in the Barcode app. - Add quantity using +1, then scan the barcode for the Pedal Bin(Barcode: 6016478556493). - Delete the newly added line and attempt to Validate. ## Observed Behavior: The system should prevent transfer validation when the destination location has not been scanned and display a notification to the user, similar to the behavior before user deleted the newly added line. ## Root cause: This issue occurs because when the delete button is pressed, the deleteLine function [1] removes the line, but the deleted line becomes the selected line due to [2] being triggered before the UI updates. As a result, the selected line is now undefined. Since the selected line is undefined, it fails to meet the condition at [3] during validation. This prevents notifications from being triggered and allows the transfer to be validated before the destination location has been scanned. [1]: https://github.com/odoo/enterprise/blob/3476d15bf8e75eb6530658dd623861b60963ab40/stock_barcode/static/src/models/barcode_model.js#L826-L836 [2] : https://github.com/odoo/enterprise/blob/327d4478128f33fb2e0c477533bd4983178abf17/stock_barcode/static/src/components/line.js#L129-L133 [3]: https://github.com/odoo/enterprise/blob/6ff158ca3a6d2d2b3d285a7f8317622844811688/stock_barcode/static/src/models/barcode_picking_model.js#L945-L948 ## Solution: We can prevent users from validating if any line has an unscanned destination location when destination-location scanning is mandatory after scanning each product. To enforce this behavior, we can track whether a line has been modified and whether a destination location has been scanned and applied to that line. This allows us to identify which lines still require destination location scanning before validation can proceed. However, line state information is currently discarded and recreated on every save. As a result, information about lines that were updated and already had their destination location scanned is lost. This may incorrectly require users to rescan the destination location, even though it was previously scanned. To address this, we preserve the destination-scanned and modified state by carrying it forward from existing lines to their corresponding newly created versions using a loop. This ensures that destination location scan status is retained and users are not asked to rescan unnecessarily. opw-6069614 Forward-Port-Of: odoo/enterprise#119363 Forward-Port-Of: odoo/enterprise#113618
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed mailings linked to marketing automation, reducing the risk of unintended spam and ensuring campaigns target the correct audience. A user error prevention and a new test have been added.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119517 Forward-Port-Of: odoo/enterprise#118759
This update corrects a bug where changes to the provider state on the Ticket Screen didn't update order filters correctly. The fix ensures that the Ticket Screen reloads with the new state, guaranteeing accurate order filtering within the UrbanPiper integration. This prevents outdated order information from being displayed.
Original PR description
Steps to Reproduce ------------------------- - Install Point of Sale and configure UrbanPiper. - Open a POS session and select a provider state from the notification popup to review orders. - While on the Ticket Screen, select a different provider state to review other orders. Issue ------- - Orders are not updated according to the newly selected state. - Previously applied filters remain unchanged. Cause -------- - Since the user is already on the Ticket Screen, changing only the provider state does not trigger a re-render. - The page was already rendered with the old filters. Fix ---- - The Ticket Screen is first switched away and then re-rendered. - This forces the screen to reload with the updated state and filters. Task: 6079663 Forward-Port-Of: odoo/enterprise#104546
15 changes
Resolved issues and error corrections
This update fixes a calculation error in the purchase order reporting, ensuring the 'Effective Days To Arrival' metric accurately reflects the time between order confirmation and receipt. Previously, the calculation was flawed, leading to incorrect lead time reporting. This change improves the accuracy of purchase data analysis.
Original PR description
Steps to reproduce --- 1. Confirm a purchase order and receive it a few days later. 2. Open Purchase, Reporting, Purchase and add the "Effective Days To Arrival" measure. Observed: the value is…
Steps to reproduce --- 1. Confirm a purchase order and receive it a few days later. 2. Open Purchase, Reporting, Purchase and add the "Effective Days To Arrival" measure. Observed: the value is counted from the line's scheduled date instead of the order date, and can even be negative when the scheduled date precedes the confirmation date. Issue --- The metric is meant to be the effective lead time, the number of days between the order confirmation and the actual receipt, falling back to the planned "days to receive" when nothing has been received yet according to [task](https://www.odoo.com/odoo/project/809/tasks/3691573). The query instead computes age(date_planned, COALESCE(date_done, date_order)), so once a receipt exists it returns date_planned - date_done (the gap between the scheduled date and the receipt) rather than date_done - date_order. https://github.com/odoo/odoo/blob/c06be48ce7277a667719fd756e0a1f63e91cda27/addons/purchase_stock/report/purchase_report.py#L20-L28 opw-6226523 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where customer pricing on the website was sometimes incorrect due to cached data. The change ensures that pricing is always recalculated based on the current website context, guaranteeing accurate pricing for customers.
Original PR description
Steps to reproduce: - enable pricelists on a website - create a backend-only pricelist with no website, no code and not selectable - assign that pricelist to a customer - access the customer…
Steps to reproduce: - enable pricelists on a website - create a backend-only pricelist with no website, no code and not selectable - assign that pricelist to a customer - access the customer pricelist once outside the website flow so it is cached - create a cart as Public User on the website - log in as that customer Issue: when the cart is reassigned from Public User to the logged-in customer, the order pricelist can switch to the cached backend-only pricelist, even though that pricelist should not be available on the website. Cause: `website_sale` filters partner pricelists depending on the current website, but the cached value of `partner.property_product_pricelist` can come from a non-website context and be reused during cart repricing. Solution: invalidate the cached partner pricelist before recomputing website order pricelists, so the value is resolved again in the current website context. opw-6251887 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a potential crash in Odoo's environment setup under Python 3.14. The fix ensures that environment data is accessed safely during initialization, preventing errors caused by concurrent modifications to the environment collection. This improves overall system stability.
Original PR description
- Type: ORM - Impact: stability / Python 3.14 compatibility _Note:_ This pattern is also present in **19.0** (`odoo/orm/environments.py`), so the fix should likely be forward-ported. ### Purpose This…
- Type: ORM - Impact: stability / Python 3.14 compatibility _Note:_ This pattern is also present in **19.0** (`odoo/orm/environments.py`), so the fix should likely be forward-ported. ### Purpose This fix prevents intermittent runtime errors occurring during registry initialization when iterating over `transaction.envs`. Under Python 3.14, `WeakSet` iteration may fail if the set is modified during traversal, leading to: `RuntimeError: dictionary changed size during iteration` - Relevant stack trace: ```bash File ".../odoo/api.py", line 586, in __new__ for env in transaction.envs: File ".../python3.14/_weakrefset.py", line 25, in __iter__ for itemref in self.data.copy(): File ".../odoo/tools/misc.py", line 1069, in __init__ self._map: dict[T, None] = dict.fromkeys(elems) RuntimeError: dictionary changed size during iteration ``` ### Root cause Unsafe snapshot creation and iteration over `transaction.envs` (`WeakSet`) while the collection may still be mutated during `Environment` lifecycle operations. `transaction.envs` is a `WeakSet` that can be modified during iteration due to: - `Environment` creation during ORM calls - `WeakRef` cleanup during registry bootstrap - re-entrant calls to `Environment.__new__` ### Additional issue in `OrderedSet.copy()` `WeakSet.__iter__()` internally relies on: ```python self.data.copy() ``` In Odoo, `self.data` may be backed by `OrderedSet`. Before this fix, `OrderedSet.copy()` rebuilt the collection from iteration: ```python return self.__class__(self) ``` This re-entered `OrderedSet.__iter__()` during copy construction itself, making the snapshot operation unsafe when weakref cleanup or recursive `Environment` creation mutated the collection during traversal. The fix copies the underlying mapping directly instead of rebuilding the collection from iteration, ensuring `copy()` remains iteration-safe and side-effect free. ### Why this is safe - `WeakSet` is not safe for concurrent mutation during iteration - `list(transaction.envs)` creates a stable snapshot before traversal - `OrderedSet.copy()` now copies the underlying mapping directly instead of rebuilding the collection from iteration - The new implementation preserves insertion order and shallow-copy semantics - No behavioral change in normal single-env execution --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must precede the end time, improving clarity for users creating shift templates.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour.
This update resolves a crash in the Asset Depreciation Schedule report that occurred when generating reports with many assets grouped together. The fix ensures the report handles missing data gracefully, preventing errors and allowing users to accurately analyze their assets even with large groups.
Original PR description
#### Description of the issue/feature this PR addresses: Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is…
#### Description of the issue/feature this PR addresses:
Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is active (large number of assets in one account group). The report becomes unusable for affected customers.
#### Current behavior before PR:
_regroup_lines_by_name_prefix sums each subline column by indexing prefix_subline['columns'][i]['no_format'] directly. Empty columns are built as {} by _build_column_dict (both col_value and col_data are None), so they have no 'no_format' key. With a comparison period enabled, an asset that has no value in the comparison period produces an empty column for that period; once prefix grouping fires (len(lines) >= prefix_groups_threshold, default 4000), the direct lookup hits that empty dict and raises KeyError: 'no_format'.
#### Desired behavior after PR is merged:
The prefix group total treats a missing 'no_format' as 0, matching the sibling caller in account_asset/models/account_assets_report.py that already guards with .get('no_format', 0). The report builds without crashing and the empty comparison column contributes 0 to the prefix group total.
opw-6225639This update ensures that stock valuation account moves created from sales orders correctly inherit the analytic account specified on the SO line. Previously, these moves didn't utilize the SO's analytic distribution, leading to incorrect accounting. This change aligns the behavior with invoices, providing more accurate tracking of costs by analytic accounts.
Original PR description
PR very similar to https://github.com/odoo/odoo/pull/263236 but here on the SO side instead of PO **Problem:** account move created by stock valuation layer does not take analytic account from SO…
PR very similar to https://github.com/odoo/odoo/pull/263236 but here on the SO side instead of PO **Problem:** account move created by stock valuation layer does not take analytic account from SO **Steps to reproduce:** - make sure you have at least one analytic account - create a storable product with categ standard automated - set a positive cost and a positive on hand quantity - create a SO for 1 quantity - on the SO line of the product, in the analytic distribution column (might need to be unfiltered) set an analytic account - confirm SO and validate delivery - click on the valuation smart button and on the book widget of the stock valuation layer **Current behavior:** the account move lines have no analytic distribution **Expected behavior:** The account move lines should inherit the analytic account from the sale order line like it's the case for the invoice. For the analytic distribution of the Invoice, the selection is : 1) take analytic distribution from SO if one 2) if not, take from distribution model if there is one 3) empty Currently for the account move lines of the svl the selection is: 1) take from distribution model if there is one 2) empty But we should use same selection as for the invoice **Cause of the issue:** When setting the analytic distribution we first try to use the one from PO/SO by calling _related_analytic_distribution() https://github.com/odoo/odoo/blob/4cc1e6884be673523f768d5ec471a1ffa19c5fb4/addons/account/models/account_move_line.py#L1157 But since the account move lines have no sale_line_ids no analytic distribution will be returned https://github.com/odoo/odoo/blob/261b15953ca89657644f52d1cb9ecda6e3b686c5/addons/sale/models/account_move_line.py#L41-L46 opw-6022695
This update prevents placeholder images from being sent during menu synchronization. Now, only the actual image URL is included when a product or category has a defined image, resulting in more efficient data transfer and a cleaner menu display. This resolves an issue where unnecessary image data was being transmitted.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430
This update fixes an issue where grouped payments were incorrectly linking older payments to new, unrelated invoices. The fix ensures that payments are accurately associated with the invoices they cover, resolving a potential reporting discrepancy. This improves the reliability of payment reconciliation.
Original PR description
Steps to reproduce --- 1. Register a grouped customer payment over several invoices, leaving one of them only partially paid. 2. Register a second grouped payment over two invoices: the partially…
Steps to reproduce --- 1. Register a grouped customer payment over several invoices, leaving one of them only partially paid. 2. Register a second grouped payment over two invoices: the partially paid one and a brand new invoice. 3. Open the first payment, its "Reconciled Invoices" smart button now lists the new invoice from the second payment, which it never paid. Issue --- The smart button is built from the stored `invoice_ids` many2many, which shares its relation table with `account.move.matched_payment_ids`. After reconciling, the register wizard links the payment to its invoices with `lines.move_id.matched_payment_ids += payment` at https://github.com/odoo/odoo/blob/f726393267a28cedd5febd2106de17ae3838f3ff/addons/account/wizard/account_payment_register.py#L1212. When the payment groups several invoices, `lines.move_id` is a multi-record recordset. Reading `matched_payment_ids` on it returns the union of the payments already linked to all those invoices, and `+=` writes that union back to every invoice as a `(6, 0, ...)` replace command. So an invoice already paid by an earlier payment spreads that earlier payment onto every other invoice grouped in the new one, including brand new invoices, which then wrongly appear on the earlier payment. opw-6188013 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where timesheets were incorrectly added to invoices after a partial refund. The fix ensures that timesheets linked to previously fully invoiced orders are no longer considered when generating new invoices, preventing duplicate invoicing and maintaining accurate financial records. This improves invoice accuracy and reduces the risk of errors.
Original PR description
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create 2 lines for the services product in the SO, invoicing policy = based on timesheets - Create 2 timesheets for both SO items - Invoice the SO - Create a credit note for line 1 => only line 2 is invoiced and line 1 is now released - Back to the SO > create invoice again > Line 2 is added to the invoice again. ### Cause of Issue: When generating the new invoice, `_recompute_qty_to_invoice` identifies timesheets linked to refunded invoices. Because the original invoice was partially refunded, all timesheets attached to that invoice match the domain used to locate timesheets—even the timesheets for line 2, which wasn't refunded. ### Fix: Ensures that lines that have already been completely invoiced are safely ignored and not inadvertently re-added to subsequent invoices. opw-6217684
This update resolves an issue where users without write access to invoice sequences would receive an error when generating global invoices in the Point of Sale (PoS) module. Previously, this prevented successful invoice creation. This change ensures invoices can be generated correctly regardless of user permissions, improving the reliability of the Mexican CFDI invoicing process.
Original PR description
When generating a global invoice, if the user has no write access to the sequence, an access error is triggered even though he can generate the invoice correctly. Steps to reproduce: ------------------- * Create some order in the PoS * Try to generate the global invoice with Marc Demo > Observation: You get an access error. * Create an invoice with CFDI to public checked * Add any product and validate the invoice * Try to generate the global invoice with Marc Demo > Observation: You get an access error. opw-6041291 Forward-Port-Of: odoo/enterprise#114478
This update ensures that shift workloads remain accurate after undoing the auto-plan feature. Previously, undoing the auto-plan would reset the allocated hours, leading to incorrect workload calculations. The fix maintains the original allocated hours while allowing the percentage to adjust based on the new slot context.
Original PR description
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation…
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation triggers recomputation of allocated_hours, causing the shift to lose its original workload value. Current Behaviour --- When resource_id is set to False during undo: - _compute_allocated_hours is triggered (depends on resource_id) - _compute_allocated_percentage is triggered (depends on allocated_hours) - Both fields are recalculated, potentially changing allocated_hours from its pre-assignment value Expected Behaviour --- Undoing auto-plan should preserve allocated_hours at its pre-assignment value while allowing allocated_percentage to adapt to the new context (open slot vs assigned resource). Fix --- Use protecting context manager in action_rollback_auto_plan_ids to prevent allocated_hours from being recomputed when resource_id is removed. This allows allocated_percentage to recalculate naturally based on slot duration while keeping allocated_hours stable. task - 4952149
This update fixes a visual issue in the portal where the Follow/Unfollow button appeared misaligned due to excessive padding. The problem was caused by a duplicated padding style being hardcoded in the portal chatter UI. Removing this duplication resolves the alignment issue and ensures a consistent user experience.
Original PR description
**Steps to reproduce:** 1. Log in as a portal user. 2. Open a shared project and then open any task within it. 3. Observe the vertical spacing above the Follow/Unfollow button and the chatter component. **Issue:** The chatter UI has incorrect vertical spacing, causing elements like the Follow/Unfollow button to sit too far down and appear misaligned. **Cause:** The pt-2 padding class was hardcoded in two separate locations: 1. The compileChatter wrapper in project_sharing_form_compiler.js. 2. The portal.Chatter XML template. When combined this caused a double-padding effect forcing excessive space. **Fix:** Removed the hardcoded pt-2 class from both the JavaScript compiler wrapper and the core XML template. This eliminates the double-padding conflict. This resolves the alignment issue in Project Sharing and does not affect the layout or functionality of other portal components. task-4203362
This update resolves an issue where the URL used for OAuth authentication with the Romanian tax authority (ANAF) was inconsistent. Previously, the URL was dynamically generated based on the user's access method, leading to mismatches and authentication failures. This change ensures the correct, standard URL is used, enabling proper tax reporting functionality.
Original PR description
The `_compute_l10n_ro_edi_callback_url` method was using `request.httprequest.url_root` to build the OAuth callback URL. The URL is derived from the current HTTP request, meaning it reflects however the user accessed the session at that moment (e.g. internal IP, localhost, non-standard port). This produces a callback URL that does not match what was registered with ANAF, breaking the OAuth flow. 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 resolves an issue where moving Odoo databases via the command line would inadvertently deregister subscription codes. A new `--move` flag has been added to the `odoo db load` command, ensuring the database's original UUID is retained during a server-to-server move. This maintains the integrity of your Odoo subscriptions.
Original PR description
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when…
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when *duplicating* a database, but it breaks the intended behaviour when *moving* a database between servers: Enterprise subscription codes are registered against the database UUID, so regenerating it deregisters the moved database. The web database manager already lets the user choose between copying and moving (the `copy` flag of the `/web/database/restore` route), but the CLI exposed no equivalent and forced a copy unconditionally. The CLI is the better tool for server-to-server moves: it isn't subject to reverse-proxy upload/timeout limits and can run unattended or interactively. ### Steps to reproduce the current limitation 1. On server A: `odoo db dump mydb mydb.zip` (Enterprise DB registered to its UUID) 2. On server B: `odoo db load mydb mydb.zip` 3. `database.uuid` has changed → the subscription is deregistered ### Fix Add a `--move` flag to `odoo db load` that maps to `restore_db(copy=False)`, keeping the original UUID. The default remains `copy=True`, so existing behaviour is unchanged. ```sh odoo db load mydb mydb.zip # unchanged: restore as a copy (new UUID) odoo db load --move mydb mydb.zip # new: restore as a move (keep the UUID) ``` ### Backport request This would be greatly appreciated as a backport to 18.0, 17.0, and 16.0 as well. Those are precisely the versions that ship the `odoo db` CLI subcommand, so the fix is applicable to all of them — which is why the backport range is 16.0 → 19.0 and stops at 16.0. Forward-Port-Of: odoo/odoo#268501
This update removes a specific message from invoice footers for B2C customers. Previously, invoices not sent via PEPPOL displayed an irrelevant message. This change ensures a cleaner and more professional experience for our B2C clients by tailoring the invoice presentation to their needs.
Original PR description
Currently, if the invoice was not sent through PEPPOL, it is indicated in the mail footer. However, this message is not appropriate for B2C customers. To avoid this, we remove this footer for customers with empty or '/' VAT (B2C). task-6167439 Forward-Port-Of: odoo/odoo#262412
5 changes
Resolved issues and error corrections
This update resolves a test failure caused by incorrectly passing raw PDF data as base64 encoded information. The fix ensures that the correct base64 format is used, preventing errors during testing. This improves the reliability of the payroll accounting tests.
Original PR description
This commit fixes an error when running the `test_employee_job_change` test on Python 3.14, which is stricter about base64 validation. Ultimately, the root issue was that raw PDF content was being passed when a base64 representation was actually expected (which is obviously invalid base64). runbot-938173
This update resolves an issue where users without write access to invoice sequences would receive an error when generating global invoices in the Point of Sale (PoS) module. The fix ensures that invoices can be generated correctly, even if the user doesn't have direct write permissions to the underlying sequence, improving the user experience for Mexican CFDI invoicing.
Original PR description
When generating a global invoice, if the user has no write access to the sequence, an access error is triggered even though he can generate the invoice correctly. Steps to reproduce: ------------------- * Create some order in the PoS * Try to generate the global invoice with Marc Demo > Observation: You get an access error. * Create an invoice with CFDI to public checked * Add any product and validate the invoice * Try to generate the global invoice with Marc Demo > Observation: You get an access error. opw-6041291
This update addresses a warning related to how Odoo uses the PyPDF library to merge pages in PDF documents. The change ensures stability and prevents potential errors by adjusting the order of operations when modifying PDF pages, improving the reliability of PDF generation.
Original PR description
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's architecture updates (specifically PR #3638 [^1] and PR #3669 [^2]), a reader's page is intended to be read-only. Mutating it directly (e.g., using `mergePage` or `compressContentStreams`) before attaching it to a writer can break internal object references and cause `NullObject` errors. This commit resolves the warning by inverting the order of operations to ensure we only mutate writable objects. The fix implements the following flow: 1. Add the unmodified source page directly to the `PdfFileWriter`. 2. Retrieve the newly created, writable output page. 3. Apply `mergePage` and `compressContentStreams` exclusively to the writer's copy of the page. [^1]: https://github.com/py-pdf/pypdf/pull/3638 [^2]: https://github.com/py-pdf/pypdf/pull/3669
This update fixes an issue where users without HR access rights on the timesheet grid view were seeing a placeholder image instead of their avatar. The fix ensures that all users can see their avatar in the timesheet grid, improving the user experience and visual consistency.
Original PR description
Steps to reproduce: ------------------- - Install the hr_timesheet module - Create a user without HR access rights - Create a timesheet - Log in with the above user - Open the kanban view Issue: ------- Instead of showing the employee's avatar, a placeholder image is displayed. Reason: ---------- The user does not have access to the hr.employee model. Fix: ----- In this commit, if the user does not have access to hr.employee,we fetch the image from the hr.employee.public model. task: 4461272
This update fixes a bug that occurred when adding recurring products to confirmed sales orders without a linked subscription plan. The fix prevents a traceback error by validating the subscription plan before generating recurring tasks, improving the user experience and preventing data inconsistencies.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700