Tuesday, February 24, 2026
16 changes · 18.0
Enhancements to existing features
This update adds tests to ensure accurate calculation of wage types on payslips, considering various employee contract details like monthly wage types and multiple leave requests across different months. These tests enhance the reliability of payroll processing for Swiss employees, particularly within the l10n_ch module.
Original PR description
This commit adds tests to the `_compute_l10n_ch_swiss_wage_ids` function to verify **Wage Types** in payslips across multiple months and with different **Monthly Wage Types** defined in an employee’s contract, as well as multiple leave requests occurring in different months. task-5906677 Forward-Port-Of: odoo/enterprise#107802
This update enhances the Odoo profiling tool by automatically tracking the time taken for database queries. Previously, profiling data was incomplete. Now, the system captures query execution times with a time limit, providing more accurate performance insights for developers to identify and address slow queries.
Original PR description
Modify the query collector so that it add an entry before the query runs and updates the time after it runs. use the async collector periodic sampling to commit the profiler after a time limit. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#215034
Resolved issues and error corrections
This update fixes an issue where duplicate preparation cards were generated when multiple items were added to a grouped order. The change ensures that only new items are sent to the kitchen, simplifying the preparation process and preventing confusion. It's designed to improve order accuracy and reduce errors in the kitchen.
Original PR description
Before this commit, when I Link 2 tables, add item on the new grouped tables and order it, I get duplicate preparation card. When we create a new product card, we need to ensure that only the new items (not sent) are actually sent as new items to prepare. Do not bother by cancelling items from the previous preparation card. Think at it as if it was a preparation ticket in paper task-id: 4735631 Community PR: https://github.com/odoo/odoo/pull/207053
This update introduces a mechanism to ensure data consistency during API calls, preventing potential conflicts when multiple users access the same records. The `_critical_section` context manager guarantees a snapshot of the database is used, avoiding errors and ensuring reliable operation. This improves the stability and accuracy of our invoicing process.
Original PR description
### The problem Suppose we have two users, A and B, who are on the same account.move and click the same button to make the same API call. Suppose B clicks their button just a bit before A's…
### The problem Suppose we have two users, A and B, who are on the same account.move and click the same button to make the same API call. Suppose B clicks their button just a bit before A's transaction commits. This is what the transactions might look like: 1. A clicks on the button, so the transaction starts... 2. A checks whether the move can be sent -> it can! 3. A acquires a lock on the account.move 4. A does the API call 5. A writes on the account.move At some point between 1 and 5, B starts their transaction: 6. B clicks on the button, so the transaction starts... Then, A commits the transaction: 7. A commits the transaction -> the lock is removed! Then: 8. B checks whether the move can be sent -> it can because B is working on an outdated snapshot of the DB. 9. B acquires a lock on the account.move -> no problem! 10. B does the API call -> no problem! 11. B writes on the account.move -> now there might be a SerializationError. But in the meantime, both A and B performed a non-idempotent external API call... ### Analysis The biggest problem is that when B checked whether the move could be sent, it wasn't working on an up-to-date snapshot of the DB. Another problem is that when B checked whether the move could be sent, it didn't yet have a lock acquired on the account.move. ### Solution We introduce a `_critical_section` context manager that ensures that: - only one database session can enter this context manager at a time for the given records (thanks to a lock); - when you enter this context manager you automatically get an up-to-date snapshot of the DB (thanks to an env.cr.commit) - committing is forbidden within this context manager (to ensure you don't lose the lock). ### How to use this context manager: - Enter it right before you check whether the API call should be made (e.g. checking whether the API was already called). - Exit it after you have written the state resulting from the API call. task-none
This update resolves a discrepancy in the calculation of CFDI invoice amounts for Mexican companies using USD transactions with Quadrum. The fix adjusts the invoice amount to precisely match the calculated MXN value, ensuring accurate reporting and compliance. This addresses a rounding issue that was impacting invoice generation.
Original PR description
Steps to reproduce: (thanks to TBS for investigating + writing the test) 1. Have a MX company with Quadrum 2. Create a USD bank transaction with `13220.00 USD` and `305147.51 MXN` 3. Create a USD…
Steps to reproduce: (thanks to TBS for investigating + writing the test) 1. Have a MX company with Quadrum 2. Create a USD bank transaction with `13220.00 USD` and `305147.51 MXN` 3. Create a USD invoice for `13220.00 USD` and send CFDI 4. Reconcile transaction and invoice 5. Click "Update payments" on the invoice => CRP20211 Looks like it comes from this rounding difference Rate is computed by odoo using `305147.51 MXN / 13220.0 USD = 23.082262481 ≃ 23.082262 MXN/USD` PAC verify the amount paid using `13220.0 USD * 23.082262 MXN/USD = 305147.50 MXN` which is not `305147.51 MXN` Solution: There is no solution by adapting the rate: - quadrum restricts the rate to 6 decimals; - rounding the rate differently (e.g. to `23.082263`) would not help because `13220.0 USD * 23.082263 MXN/USD = 305147.52 MXN` which again is not `305147.51 MXN`. So, the only solution that I can think of is to adapt the amount in company currency so that it is exactly `round(amount_in_payment_curr / rate_rounded_to_6_decimals)`, i.e. in the example, change it to `305147.50 MXN`. In tests, Quadrum seems to accept this. We don't perform the modification for other PACs. opw-4222310
This update fixes an issue where the number of valid holiday allocations wasn't accurately displayed when a holiday allocation started in the previous year. The fix ensures the smart button on the time off type page correctly reflects the total number of valid allocations, regardless of their start date, improving data consistency and reporting.
Original PR description
__ ## Short functional explanation of the error When setting the start date for a time off allocation to the previous year, it is not taken into account when computing the count of employee…
__ ## Short functional explanation of the error When setting the start date for a time off allocation to the previous year, it is not taken into account when computing the count of employee allocations on the time off type page. ## Reproduction Steps 1. Go to Time off > Configuration > Time off Types and click on any time off type. 2. A smart button Allocations should appear with a number in it. Note the number and click on the button. 3. If no allocation exists yet, create one. Otherwise, click on an already existing allocation. 4. Set the start date of the validity period to any date last year. Set the ending date so that the allocation is still valid as of now. 5. Go back to the Time off type page and look at the number on the Allocations smart button. ### Expected behavior As the allocation we set is still valid, the number shouldn't have changed. ### Unexpected behavior The allocation number has been decreased. However, when we click on the smart button, the same number of valid allocations will show. This creates an inconsistency between the smart button and the allocation page, as the smart button should show the number of valid allocations, and when landing on the allocation page, the results are automatically filtered by validity. ## Origin of the issue The domain of the allocations to take into account when computing the count of valid allocations is defined here: https://github.com/odoo/odoo/blob/2264f330859b79010b227e3a9fda1075de8ed4e8/addons/hr_holidays/models/hr_leave_type.py#L297-L304 This doesn't take into account valid allocations that started during the previous year. The inconsistency with the allocation page can be seen here: https://github.com/odoo/odoo/blob/2264f330859b79010b227e3a9fda1075de8ed4e8/addons/hr_holidays/views/hr_leave_allocation_views.xml#L40-L46 Where the filter is defined based on today, rather than on the whole year, unlike above. __ opw-5504272
This update resolves a crash in the HTML Editor component caused by overly aggressive sanitization of attributes. The fix involves a simple encoding/decoding process to ensure data stored in the editor's embedded components remains intact, preventing unexpected errors. This improves stability and reliability of the editor.
Original PR description
Prior to this commit, since DOMPurify v3.1.2 (and more precisely since usage of v3.1.5 in Odoo), the JS sanitization process aggressively removes html attributes with `-->`, `<style` and `<title` for…
Prior to this commit, since DOMPurify v3.1.2 (and more precisely since usage of v3.1.5 in Odoo), the JS sanitization process aggressively removes html attributes with `-->`, `<style` and `<title` for security reasons (see [1]). However `html_editor` embedded components use `data-attributes` (`data-embedded-props` and `data-embedded-state`) to store various kind of data as a JSON string. Obviously, such JSON strings easily match the DOMPurify regex and these attributes are therefore removed, which results in an Editor crash. There are multiple reasons why such values are acceptable as is for the `html_editor` usage: - only `HTMLElement` instances are sanitized, never a string, therefore there is no `DOMParser` to trick with invalid HTML. - values in these attributes are always/exclusively parsed as JSON strings, and the editor will crash if the value is not a legit JSON. - values in these attributes are HTML escaped by the python sanitizer when the serialized html is sent to the server. - values in the JSON parsed object are at worst rendered as plain text (never as HTML or other parsed formats). - values in the JSON parsed object are never executed as JS (only serializable primitives are stored). Therefore, the suggested solution is to encode the values during sanitization, and decode just after, to keep the rest of the codebase simple and explicit. [1]: https://mizu.re/post/exploring-the-dompurify-library-hunting-for-misconfigurations#dompurify-gt-3.1.2-safe-for-xml task-5960707
This pull request addresses several stability issues within the Hoot testing framework. It includes fixes for test logging, error reporting, and ensures proper cleanup of test environments, ultimately improving the reliability of our automated tests. These changes are focused on enhancing the testing process itself.
Original PR description
Fixes for tests and testing framework. See commit messages for details. Enterprise: https://github.com/odoo/enterprise/pull/107286 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update enhances the reliability of self-order transactions within Odoo Point of Sale. By aligning the data validation rules with standard POS orders, the system now catches more errors and ensures data accuracy. This improves the overall customer experience and reduces potential issues with self-order processing.
Original PR description
*: pos_online_payment_self_order, pos_restaurant, pos_self_order This commit improves the data validation of pos self order by using the same validation as the one used for regular pos order.
This update resolves an issue preventing the SAF-T (D406 Asset Declaration) report from correctly identifying suppliers for fixed assets. The fix ensures that supplier information is accurately retrieved by expanding the data source to include depreciation lines, addressing a discrepancy caused by bills posted in previous months.
Original PR description
**Steps to reproduce:** - Install l10n_ro_saft - Switch to a Romanian company (e.g. RO Company) - Create an asset model: * Method: Straight Line * Duration: 12 Months - Configure a "Fixed Assets"…
**Steps to reproduce:** - Install l10n_ro_saft - Switch to a Romanian company (e.g. RO Company) - Create an asset model: * Method: Straight Line * Duration: 12 Months - Configure a "Fixed Assets" account: * Automate Asset: Create and validate * Asset Model: [the asset model created above] - Create a bill: * Vendor: [create a new vendor] * Bill Date: [last month] * Invoice Line: [A line with the fixed asset account] - Confirm the bill - Go to "Accounting / Reporting / Audit Reports / General Ledger" - Select the current month (The fixed asset account should be present) - In the cog menu, select "SAF-T (D406 Asset Declaration)" **Issue:** A traceback is raised while trying to display the name of a supplier. **Cause:** To display the supplier name of an asset, a dict having the id of the customer or supplier as key (i.e. partner_detail_map) is used. This dict is build by getting the list of all partners linked to a posted journal item on an asset (or liability) account in the period of the report. In this case, it's the current month. However, the created bill has been posted the month before. So no journal item is found for the vendor that has been created just for the bill and therefore there is no key for him in the dict, which leads to the error when trying to get the id of the supplier of the asset in the dict. **Solution:** Instead of just fetching the posted entries linked to a receivable or payable account in order to get the list of the potential customers and suppliers, we also fetch the depreciation lines that are linked to an asset account and can still be in draft. opw-5499918
This update fixes a problem where users attempting to print resumes with incorrect templates received only a generic error message. The fix now provides a detailed traceback, making it easier for administrators to identify and resolve the underlying template issues. This improves the user experience and streamlines troubleshooting.
Original PR description
Currently, when a user tries to print a resume with an invalid template there’s no traceback to show what went wrong. **Steps to produce:** * Install `hr` with demo data * Modify the view…
Currently, when a user tries to print a resume with an invalid template there’s no traceback to show what went wrong. **Steps to produce:** * Install `hr` with demo data * Modify the view `report_employee_cv` by adding `<div t-if=o.no/>` * Print resume of any employee **Observed Behavior:** Currently it only shows the error in [1], with no context or traceback to explain what went wrong. **Root cause:** * This happens because the route doesn’t include the website parameter. Without it, the system treats the route as non–front end [2], so the error handler never reaches [3].That means [4] never loads the templates [5], and the browser just gets a plain response at [6]. **Solution:** * Catching and raising UserError shows appropriate traceback. **Before:** <img width="1606" height="796" alt="image" src="https://github.com/user-attachments/assets/d5432fbf-d016-46a9-bade-8e8408848c66" /> **After:** <img width="1832" height="928" alt="image" src="https://github.com/user-attachments/assets/6f0413ca-a82a-487d-888f-81be6f0fab03" /> [1]: https://drive.google.com/file/d/1qJLkFGw4bEclqKihdUI-4bjJofdFArEc/view?usp=sharing [2]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L386 [3]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L611 [4]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L573-L576 [5]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/views/http_routing_template.xml#L139 [6]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L575 Related: https://github.com/odoo/enterprise/pull/100142 opw-5167898 Forward-Port-Of: odoo/odoo#237262
When printing PDF payslips with incorrect document layouts, users now receive a helpful traceback instead of a generic error message. This allows administrators to quickly identify and correct the issue with the document template, preventing further printing failures. This enhancement improves the user experience and simplifies troubleshooting.
Original PR description
Currently, when a user tries to print a PDF report with an invalid document layout template, there’s no traceback to show what went wrong. **Steps to produce:** * Install payroll with demo data. *…
Currently, when a user tries to print a PDF report with an invalid document layout template, there’s no traceback to show what went wrong. **Steps to produce:** * Install payroll with demo data. * Settings > Configure Document Layout then Edit Layout * Add non-existent field `<div t-if='o.no'/>` * Payroll > All payslips > print any payslip **Observed Behavior:** * Currently it only shows the error in [1], with no context or traceback to explain what went wrong. **Root cause:** * This happens because the route doesn’t include the website parameter. Without it, the system treats the route as non–front end [2], so the error handler never reaches [3].That means [4] never loads the templates [5], and the browser just gets a plain response at [6]. **Solution:** * Catching and raising UserError shows appropriate traceback. **Before:** <img width="1601" height="507" alt="image" src="https://github.com/user-attachments/assets/f7f208f0-cdd7-410e-87e7-32a9651df9d8" /> **After:** <img width="1847" height="928" alt="image" src="https://github.com/user-attachments/assets/c73522d6-2632-422b-b1d1-234e6c61ed2e" /> [1]: https://drive.google.com/file/d/1qJLkFGw4bEclqKihdUI-4bjJofdFArEc/view?usp=sharing [2]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L386 [3]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L611 [4]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L573-L576 [5]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/views/http_routing_template.xml#L139 [6]: https://github.com/odoo/odoo/blob/e4e2dca73213c33c487033dd404a7ca335960a66/addons/http_routing/models/ir_http.py#L575 Related:https://github.com/odoo/odoo/pull/237262 opw-5167898 Forward-Port-Of: odoo/enterprise#100142
This update corrects a discrepancy in the Romanian tax reports, reflecting the recent VAT rate changes (19% to 21% and 5%/9% to 11%). The changes ensure the reports accurately match current Romanian tax regulations, including the addition of necessary tax rates and setting unused rates to inactive status to maintain report functionality.
Original PR description
Romanian VAT has increased from 19% to 21% and from 5%/9% to 11%, some taxes were added previously to the module but they were not reflected in the tax report, also other taxes were missing in order for the report to replicate the current up to date version issued by the romanian government. Forward-Port-Of: odoo/odoo#241529
This update ensures that NACHA payment files accurately reflect the actual bank account holder's name, rather than the customer's name in Odoo. Prioritizing the bank account holder's name improves payment processing accuracy and compliance with NACHA regulations.
Original PR description
The NACHA entry detail was using the partner's name (res.partner.name) for the Individual Name field. This should instead prioritize the Account Holder Name (acc_holder_name) from the bank account, as this reflects the actual name on the bank account which may differ from the partner's name in Odoo. The code now uses bank.acc_holder_name if set, and falls back to payment.partner_id.name if not set. Forward-Port-Of: odoo/enterprise#105582
A bug was causing the 'Publish & Send' button to disappear in the scheduling interface. This update removes a previous fix that inadvertently removed this button. The change ensures the button remains visible, allowing users to properly send their schedules.
Original PR description
## Issue Since commit https://github.com/odoo/enterprise/commit/a0f44c2bdb2, `planning_test_tour_no_email` is failing when trying to click on the (missing) `Publish & Send` button. ## Cause The…
## Issue
Since commit https://github.com/odoo/enterprise/commit/a0f44c2bdb2, `planning_test_tour_no_email` is failing when trying to click on the (missing) `Publish & Send` button.
## Cause
The commits adds the `my_planning_action` attribute to the context when opening the `Schedule by Resource`. This allowed to display the `I Take It!` button when opening an open shift, but it also removed the `Publish & Send` button, as its condition to be invisible consistently contains `context.get('my_planning_action')` [[1](https://github.com/odoo/enterprise/blob/6892fbda8717effdf3eac06eb6783f1c238ce789/planning/views/planning_views.xml#L11), [2](https://github.com/odoo/enterprise/blob/6892fbda8717effdf3eac06eb6783f1c238ce789/planning/views/planning_views.xml#L78-L79), [3](https://github.com/odoo/enterprise/blob/6892fbda8717effdf3eac06eb6783f1c238ce789/planning/views/planning_views.xml#L273-L274)].
## Fix
The objective is to fix the bug from previous commit https://github.com/odoo/enterprise/commit/a0f44c2bdb2 differently. Instead of adding the `my_planning_action` to the context, we remove the conditions on the `I Take It!` button.
runbot-241028This update corrects a bug where a previously revoked portal user could be incorrectly set as the default public user for a new website. This prevented potential confidentiality issues and ensures that website public user assignments are based on current permissions. The fix temporarily archives revoked users to maintain reactivation options.
Original PR description
**Steps to reproduce:** - Go to a Contact - Go to the actions dropdown menu of the record - Grant Portal Access - Revoke that Access - Create a new Website in the same Company that Portal Access was…
**Steps to reproduce:**
- Go to a Contact
- Go to the actions dropdown menu of the record
- Grant Portal Access
- Revoke that Access
- Create a new Website in the same Company that Portal Access was granted
- That Contact's user will be set as the Public User for the new Website
- New orders and other default public user behavior will be assigned to this user
- The user will be mentionned in non-logged interactions
**Issue:**
Archived portal user are set as public user when revoked, and the default public user of a website is set on create to the first public user it finds in `_get_public_user`:
```
public_users = self.env.ref('base.group_public').sudo().with_context(active_test=False).users
public_users_for_company = public_users.filtered(lambda user: user.company_id == self)
if public_users_for_company:
return public_users_for_company[0]
```
This seems to be an issue as such user can be reactivated or be assigned to some transactions it has not made (confidentiality issue).
**Fix:**
Not sure of the best way to fix this. We could ensure new website always creates a new public user, or find a better way to use by default the `self.env.ref('base.public_user')` (or its company-specific copies) for the company of the website during creation (or in `_get_public_user`).
For now the fix archive the revoked portal user (keeping its previous non-public groups), to still be able to reactivate it later on, without mistaking it for the default public user of a company.
Also we can't remove the `with_context(active_test=False)` as default public user always seems to be disabled.
related: https://github.com/odoo/odoo/commit/83e22fd0636748c4fe1058fb93adfad2623fc31b
*Reapply the reverted fix properly to avoid template issues and blocking flows (https://github.com/odoo/odoo/pull/239477 and https://github.com/odoo/odoo/pull/236462)*
opw-4760550