Thursday, February 19, 2026
21 changes · saas-19.1
New functionality added to Odoo
This update adds a new module to automatically send CFDI XML and PDF documents with payslips to employees in Mexico. This fulfills a requirement for compliant payroll reporting, streamlining the process and ensuring accurate record-keeping for Mexican businesses using Odoo Enterprise.
Original PR description
Introduce a new module to enable sending CFDI XML with payslips. task: 5114611 Forward-Port-Of: odoo/enterprise#102692
This update introduces support for JoFotara's Point of Sale (POS) system within Odoo. It allows for the generation of electronic invoices (UBL format) directly from POS orders, streamlining the invoicing process for JoFotara businesses. This enhances integration and simplifies compliance with local regulations.
Original PR description
This commit adds support to JoFotara for pos.order model. task-4213323 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243844
Resolved issues and error corrections
This update optimizes the MPS report to handle large production schedules more efficiently. By reducing the amount of data fetched and minimizing unnecessary queries, the report now runs significantly faster and consumes less memory, preventing potential errors. This improves the overall responsiveness of the system for users generating these reports.
Original PR description
Problem: When running the MPS report on a large number of production schedules, if the associated number of stock moves is high, the _get_moves_and_date method can cause a memory error. Solution: We…
Problem:
When running the MPS report on a large number of production schedules, if the associated number of stock moves is high, the _get_moves_and_date method can cause a memory error.
Solution:
We will fetch only the necessary fields to reduce queries and memory usage and set prefetch_fields=False to further reduce memory usage.
Benchmarks:
Run locally on a dupe of customer's db.
Time/queries measured by requests to /get_mps_view_state Memory measured using memray on method get_production_schedule_view_state()
<table>
<tr>
<th rowspan="2"># of Production Schedules</th>
<th colspan="3">Before</th>
<th colspan="3">After</th>
</tr>
<tr>
<th>Time</th>
<th># of Queries</th>
<th>Memory usage</th>
<th>Time</th>
<th># of Queries</th>
<th>Memory usage</th>
</tr>
<tr>
<td>20</td>
<td>22.846s</td>
<td>1,379</td>
<td>882.0MB</td>
<td>8.046s</td>
<td>1,180</td>
<td>103.4MB</td>
</tr>
<tr>
<td>300</td>
<td>41.098s</td>
<td>6,297</td>
<td>1.0GB</td>
<td>43.694s</td>
<td>5,732</td>
<td>363.5MB</td>
</tr>
<tr>
<td>1000</td>
<td>N/A (MemoryError)</td>
<td>N/A (MemoryError)</td>
<td>>2GB</td>
<td>88.416s</td>
<td>22,629</td>
<td>1.1GB</td>
</tr>
</table>
Average memory usage reduction: 75%
opw-5225472
Forward-Port-Of: odoo/enterprise#106392This update resolves an issue preventing some iPhone users (particularly the iPhone 13 Pro) from correctly focusing on barcodes when scanning. A temporary workaround – a zoom slider – has been implemented to address this limitation, ensuring consistent barcode scanning functionality across all mobile devices. This improves the mobile sales process by allowing users to reliably scan barcodes.
Original PR description
This commit resolves an issue where certain mobile devices with multiple lenses (notably iPhone 13 Pro) failed to focus on barcodes at close range. Since the Web API does not allow direct manual focus control in Safari iOS, a zoom slider has been added as a workaround to help the camera sharpen the image. Note: While Chrome on Android supports direct focus adjustment, this zoom-based solution provides a consistent fix for all mobile users. Steps to reproduce: * Open Odoo on Mobile * Go to Sale app * Create a new SO * Add a product * Select the barcode icon to open the modal * Try to scan a barcode (Object is near the phone) => Bug opw-5870885 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#249292
This update resolves an issue preventing standard payroll users from accessing the 'One-time payments' feature within Swiss company contracts. The fix allows payroll officers and managers to open this functionality, ensuring they can correctly manage elm transmissions. This improves usability for payroll operations.
Original PR description
Steps to reproduce: ------------------- 1. Install l10n_ch_hr_payroll_elm_transmission. 2. Switch to a Swiss company and create a new employee. 3. Create a new internal user with Payroll…
Steps to reproduce: ------------------- 1. Install l10n_ch_hr_payroll_elm_transmission. 2. Switch to a Swiss company and create a new employee. 3. Create a new internal user with Payroll Officer/Manager access. 4. Log in as that user, create a contract, and click on "One-time payments". Issue: --------- A Traceback with AccessError: ```You are not allowed to access 'Action Window' (ir.actions.act_window) records.``` Cause: ---------- https://github.com/odoo/enterprise/blob/9e39b4b85fcb9f6ed5b21b942796b76b8a6eefdb/l10n_ch_hr_payroll_elm_transmission/models/hr_contract.py#L195 The code attempts to call `.read()` on an `ir.actions.act_window` record. Standard users typically do not have read access to window action records, resulting in an **AccessError** even if they have rights to the payroll data. Solution: ------------- Use [_for_xml_id](https://github.com/odoo/odoo/blob/93bd4d018d815b5f98d1eaaac3ae613aefbdba56/odoo/addons/base/models/ir_actions.py#L187) to return action content for the provided xml id in a safe way by doing [sudo](https://github.com/odoo/odoo/blob/93bd4d018d815b5f98d1eaaac3ae613aefbdba56/odoo/addons/base/models/ir_actions.py#L205) internally to bypass the access restriction. opw-5491467 Forward-Port-Of: odoo/enterprise#107628 Forward-Port-Of: odoo/enterprise#106598
This update adjusts the Swiss tax reports to accurately include account 2970, which represents the 'Annual profit or annual loss' account. The change ensures correct reporting for Swiss tax compliance. This fix resolves a discrepancy in the account selection process.
Original PR description
This recent commit: odoo/enterprise@d223f826eaafa3189846b555af16b240f91936ba changed the formula for `account_financial_report_line_ch_290_a_balance` from: ```py [('account_id.code', '>=', '290'),…
This recent commit:
odoo/enterprise@d223f826eaafa3189846b555af16b240f91936ba
changed the formula for `account_financial_report_line_ch_290_a_balance` from:
```py
[('account_id.code', '>=', '290'), ('account_id.code', '<', '2991'), ('account_id.account_type', '!=', 'equity_unaffected')]
```
to:
```py
[('account_id.code', '>=', '290'), ('account_id.code', '<', '2970')]
```
The main goal of the commit was to remove the unaffected earnings account from the CH reports. While doing so, the formula was also modified by replacing `account_id.code = 2991` with `account_id.code = 2970`.
However, since the condition uses the `<` operator, the account with `code = 2970` is not taken into account. Account `2970` is the last account that should be considered before `Annual profit or annual loss`. see:
https://github.com/odoo/odoo/blob/19.0/addons/l10n_ch/data/template/account.account-ch.csv#L106
Ticket [link](https://www.odoo.com/odoo/project.task/5387092)
opw-5387092
Forward-Port-Of: odoo/enterprise#102247This update fixes an issue where tables copied from the Knowledge editor were only partially copied, resulting in incomplete table structures when pasted elsewhere. The change ensures that tables are fully copied, regardless of whether the content is editable or locked, providing a consistent user experience. This improves the usability of the Knowledge feature for creating and sharing tables.
Original PR description
Problem: In Knowledge, when adding a clipboard block and inserting a table inside it, clicking on the copy button only copies the text inside the table instead of the full table structure. Cause: In `html_viewer`, the copy logic clones only the deepest selected node. In contrast, `html_editor` (via `clipboard_plugin`) copies the entire selection range. This difference causes inconsistent behavior between editable and locked content. Solution: Align the behavior by copying the full selection in `html_viewer`, ensuring tables and other complex structures are copied entirely and consistently. Steps to reproduce: - Open Knowledge. - Add a clipboard block. - Insert a table inside the block. - Lock the content. - Click the copy button. - Paste into any editable field. - Observe that only the text (not the table) is pasted. opw-5476320 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#247930
This update resolves an issue where grouped tax reports were generating incorrect results when invoices included both positive and negative tax amounts. The fix ensures that all tax line amounts, including negative ones, are correctly considered during report generation, preventing errors and ensuring accurate tax reporting.
Original PR description
The grouped tax reports are broken if an invoice is created with 2 lines on 2 different income accounts. [A previous…
The grouped tax reports are broken if an invoice is created with 2 lines on 2 different income accounts. [A previous commit](https://github.com/odoo/odoo/commit/48d60151254045768d5aac1b29c5acf84b70cef2) modified the query responsible for the construction of the grouped reports. It only keeps the base lines of type entry which have a balance of the same sign as the tax line. Yet in our case, the CABA move is of type 'entry'. It has only one tax line with a positive amount because the taxes amounts on each line are added. But the balance of the negative line is negative. So the query will only consider the positive line hence the error. So now, the logic is only considering lines with the same sign to avoid entries where the invoice lines and the refund lines are both there. This is why it only checks for moves of type 'entry'. We also ignore the check for CABA moves, i.e. moves where `tax_cash_basis_origin_move_id` is defined. Steps to reproduce: - Activate Cash Basis in the Settings - Create a tax based on payment - Create an invoice with two lines: - One with a negative amount, an income account and the created tax - One with a positive amount big enough to compensate the previous line, a different income account and the same tax - Confirm - Click "Pay", validate the payment - In the Dashboard > Bank journal > Create a reconciliation of the amount of the invoice - Reconcile it with the invoice - Accounting > Reporting > Tax Return - Select "Group By: Account tax" Ticket [link](https://www.odoo.com/odoo/project.task/5089790) opw-5089790 Forward-Port-Of: odoo/odoo#249099 Forward-Port-Of: odoo/odoo#239081
This update resolves an issue where grouped tax reports were generating incorrect results when invoices included both positive and negative tax amounts. The fix ensures that all tax lines, including those with negative balances (CABA moves), are properly considered during report generation. This improves the accuracy of tax reporting.
Original PR description
The grouped tax reports are broken if an invoice is created with 2 lines on 2 different income accounts. [A previous…
The grouped tax reports are broken if an invoice is created with 2 lines on 2 different income accounts. [A previous commit](https://github.com/odoo/odoo/commit/48d60151254045768d5aac1b29c5acf84b70cef2) modified the query responsible for the construction of the grouped reports. It only keeps the baselines of type 'entry' which have a balance of the same sign as the tax line. But in our case, the CABA move is of type 'entry'. It has only one tax line with a positive amount because the taxes amounts on each line are added. But the balance of the negative line is negative. So the query will only consider the positive line hence the error. So now, the logic of the only considering lines with the same sign is to avoid entries where the invoice lines and the refund lines are both there. This is why it only checks for moves of type 'entry'. We also ignore the check for CABA moves, i.e. moves where `tax_cash_basis_origin_move_id` is defined. Steps to reproduce: - Activate Cash Basis in the Settings - Create a tax based on payment - Create an invoice with two lines: - One with a negative amount, an income account and the created tax - One with a positive amount big enough to compensate the previous line, a different income account and the same tax - Confirm - Click "Pay", validate the payment - In the Dashboard > Bank journal > Create a reconciliation of the amount of the invoice - Reconcile it with the invoice - Accounting > Reporting > Tax Return - Select "Group By: Account tax" Community PR: odoo/odoo#239081 Ticket [link](https://www.odoo.com/odoo/project.task/5089790) opw-5089790 Forward-Port-Of: odoo/enterprise#107707 Forward-Port-Of: odoo/enterprise#101601
This update resolves an issue where DHL shipping rate calculations failed when requested for dates outside of DHL's business hours. Adding a 'next business day' flag ensures rates are accurately calculated, preventing errors and ensuring reliable shipping options for our customers. This addresses a previous error causing 'Product not found' issues.
Original PR description
Before this commit, there was an issue when trying to get the rates for DHL shipping late in the day. The issue happened because `plannedShippingDate` fell outside of the working hours. This commit adds the nextBusinessDay flag for the rating request to avoid the error. Error: ``` Product not found 996: The requested product(s) not available for the requested pickup date. Process ID associated for this transaction') ``` opw-5393684 Forward-Port-Of: odoo/enterprise#107153
This update fixes a potential issue where global invoices sent from the POS in Mexico could fail due to timeouts when interacting with the SAT portal. Increasing the read timeout for these requests helps prevent duplicate invoice submissions and ensures accurate data transmission, improving the reliability of tax filing.
Original PR description
**Fix:** Increase the read timeout for POST requests to SW sapien PAC. It may prevent timeout issue when sending a global invoice from the POS with a lot of POS orders that could lead to duplicated documents on the SAT portal when retrying to send the global invoice again. opw-5347962 Forward-Port-Of: odoo/enterprise#107735
This update optimizes how Odoo retrieves related data, preventing performance slowdowns that can occur when fetching large amounts of information. By deduplicating data during the fetching process, the system now responds more quickly, especially when accessing multiple related records. This results in a smoother and faster user experience.
Original PR description
Various improvements to avoid non-linear growth of returned values when iterating over prefetches. Traversing a relational field introduces a duplication factor in the returned values. `records |=…
Various improvements to avoid non-linear growth of returned values when iterating over prefetches. Traversing a relational field introduces a duplication factor in the returned values. `records |= more` is syntactic sugar for `records = records | more`, which does not modify the recordset in place but makes one from scratch. Therefore the time complexity is not `O(len(more))` but `O(len(records) + len(more))`, which is what makes it quadratic when used in a loop. Since refactor in https://github.com/odoo/odoo/pull/229057, this quadratic complexity is introduced in the prefetching, too. Changes: - Keep same prefetch when accessing a single key as when iterating over a recordset. Small gain and more consistent results. - When iterating over prefetches, deduplicate at source. Without this, the overhead of the generator can be huge for each returned value, since the same value might be returned many times. In less trivial cases (like traversing two relational fields and making unions with it), the time speedup is several orders of magnitude.
This update resolves a problem where salary inputs needed to be manually triggered, preventing accurate calculations for advance salary recovery. The update clarifies the process by moving a key function to each salary structure file and removing a redundant file, ensuring correct salary data population.
Original PR description
Purpose: the salary inputs have to be manually triggered, which causes issues when it comes to populating the salary input for the advance salary recovery. Fix: moved the function `update_properties_definition_domain` to each salary structure data file to be more obvoius and removed `l10n_tr_hr_payroll_data` as the file wasn't in the manifest task-id: 5912475
This update corrects a problem preventing wage statements in Switzerland to be properly sent out. The fix addresses an error in the HR payroll module, ensuring accurate and timely delivery of these important financial documents. This improves compliance and reduces potential delays for employees.
Original PR description
Forward-Port-Of: odoo/enterprise#107827
This update significantly speeds up the salary simulation process within the HR system. By adding an index and avoiding unnecessary image calculations, the simulation now runs much quicker – nearly five times faster. This improves the user experience and reduces the time spent configuring employee salaries.
Original PR description
Description ----------- Add missing index on `hr.expense.employee_id` as it's used in a few places as a transitive dependency. Avoid computing images for new employee versions during simulation, as it's loading external dependencies, incurring a performance cost. Benchmark --------- On a staging database, opening the salary configurator and clicking on 'Simulation' when selecting a new car took: | Timings for | Before | After | Speed up | |--------------------|--------|--------|----------| | `onchange_benefit` | ~750ms | ~160ms | 4.6x | | `update_salary` | 2.3s | 1.1s | 1.9x | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241901
This update streamlines the process of generating salary simulations by introducing a standardized context manager. This ensures consistent setup and teardown of necessary operations, reducing potential errors and improving the reliability of the simulation process. It also enforces correct usage of required context keys.
Original PR description
Description ----------- Getting an `hr.version` from an `offer` during simulation is done in a savepoint, preceded and followed with flushing of the environment and some post-cleanup. This is verbose…
Description ----------- Getting an `hr.version` from an `offer` during simulation is done in a savepoint, preceded and followed with flushing of the environment and some post-cleanup. This is verbose and error-prone, as it's done at each call site of `hr.contract.salary.offer._get_version` and `hr.version._generate_salary_simulation_payslip` (or any other future method that may require such a savepoint). These methods have a comment that mentions *requiring* a savepoint to be called, but nothing is enforcing it, so a bug due to oversight is bound to happen. Context keys are also injected a bit everywhere like `salary_simulation` and `tracking_disable`, without much consistency, and adding to the visual clutter. This commit introduces a little context manager called `hr_version_context` that manages the creation of the savepoint, the setup and teardown necessary, and the setting of the keys in the context. It's accompanied by a decorator `@requires_hr_version_context` that will fail if the caller didn't use `hr_version_context` before invoking the marked method. This ensures: - Correct creation of the savepoint and its related pre-/post-operations - Apply context keys consistently - Ensure methods that require such setup *cannot* be called without it. Forward-Port-Of: odoo/enterprise#103187
This update fixes a discrepancy in accounting calculations within the Point of Sale (POS) for Mexican tax reporting (l10n_mx_edi_pos). Previously, the POS wasn't correctly processing assets, leading to inaccurate amounts. This change ensures that POS transactions align with the calculations performed in Python, guaranteeing accurate financial reporting.
Original PR description
Before this commit, the needed assets were not correctly loaded in the POS, which caused the amounts to be different from the ones computed in python. opw-5935191 Forward-Port-Of: odoo/enterprise#107657
This update resolves several issues impacting the Odoo Profiler's reliability, specifically related to thread management and data collection. The fixes ensure the profiler consistently collects accurate data without errors or delays, improving debugging and performance monitoring.
Original PR description
Multiple fixes for the Profiler. Issues: - Python throws cannot join current thread when using the entry count with memory and traces async profilers. - The periodic profilers were waiting the full amount of the sleep before ending. - When using the entry_count, the memory profiler was throwing a non serializable object error - Sometimes the memory collector throws an error that the tracemalloc needs to be started so that it collects. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232551
This update resolves an issue where Odoo was incorrectly including an UETR tag in ISO 20022 payment files, causing rejection by strict banks. The change ensures compliance with SEPA regulations, preventing errors and guaranteeing successful payment processing for our European users. This improves compatibility with major banking systems.
Original PR description
In Odoo 18.0, when a user selects the pain.001.001.09 format (ISO 20022), Odoo systematically includes the <UETR> (Unique End-to-end Transaction Reference) tag for every transaction. While valid under the general ISO 20022 XML schema, the <UETR> tag is not authorized by the EPC (European Payments Council) within the standard SEPA Credit Transfer (SCT) Rulebook. Strict banks (e.g., UBS, German banks) reject the entire file with errors such as: "No child element is expected at this point" when an UETR is detected in a domestic or intra-SEPA flow. Task: 5871528 Forward-Port-Of: odoo/enterprise#106537 Forward-Port-Of: odoo/enterprise#105518
This update ensures Odoo's Mexican payroll (l10n_mx_hr_payroll) correctly complies with Mexican Social Security Law regarding minimum wage deductions for IMSS, ISR, and subsidies. The changes automatically adjust payroll XML output to accurately reflect these exemptions, improving payroll accuracy and reducing potential compliance risks.
Original PR description
According to the Mexican Social Security Law, when an employee's total monthly earnings (including bonuses and commissions) are equal to or less than the monthly minimum wage (l10n_mx_daily_min_wage…
According to the Mexican Social Security Law, when an employee's total monthly earnings (including bonuses and commissions) are equal to or less than the monthly minimum wage (l10n_mx_daily_min_wage * 365 / 12), they are exempt from social security contributions and income tax, also they lost the subsidy benefit. - The next rules are zeroed out when the gross salary is equal or less than the minimum wage: - IMSS_EMPLOYEE: IMSS Total (Employee) - ISR: ISR (Income Tax) - SUBSIDY: Used Subsidy - IMSS_EMPLOYEE and ISR are omitted from the generated XML. - As the ISR is zero, the `totalDeducciones` attribute on the `nomina12:Nomina` node should be removed. - The SUBSIDY should be present in the `SubsidioCausado` attribute on the `nomina12:SubsidioAlEmpleo` node, but the `Importe` attribute on the `nomina12:OtroPago` node should be 0.0. This change requires updates to existing standard tests, as some previous test cases used amounts lower than the minimum wage. target: 19.0 task-5226971 Forward-Port-Of: odoo/enterprise#104668
This update resolves an issue where formatting links in the HTML editor would create duplicate links and incorrectly apply styles. The fix ensures links are treated as single units, wrapping selected text in a `<font>` tag for formatting, and addresses related issues with color classes and block splitting to improve formatting consistency.
Original PR description
Before this commit: when formatting partially a link, the link is split at the selection and formatted. This causes duplicated links. After this commit: we consider links are unsplittable, thus…
Before this commit: when formatting partially a link, the link is split at the selection and formatted. This causes duplicated links. After this commit: we consider links are unsplittable, thus formatting on links will wrap the selected part in a <font> tag. commit 2: [FIX] html_editor: solve infinite loop of links with color class Before this commit: we have a fix https://github.com/odoo/odoo/commit/96bc421d30f34a8bfc10dde93c2f283809a8a3e3 which to be able to remove the style classes in the link element After this commit: We don't consider the style class in the link element as `hasColor`, because the style classes come from the template code, which is hard-coded xml. Removing them, the user won't be able to add it back. For example, on a product page, edit the `Terms and conditions` link, do nothing and save, the muted color is forced removed. Note that another fix https://github.com/odoo/odoo/commit/f5fc55f19f89041c8391ff81b127ffce0898f89f is also removed cause it was a fix for https://github.com/odoo/odoo/commit/96bc421d30f34a8bfc10dde93c2f283809a8a3e3. The tests belonging to https://github.com/odoo/odoo/commit/96bc421d30f34a8bfc10dde93c2f283809a8a3e3 are adapted, and those of https://github.com/odoo/odoo/commit/f5fc55f19f89041c8391ff81b127ffce0898f89f are kept as future safeguards of list coloring. commit 3: [FIX] html_editor: extra check on targetnode when splitting blocks Before this commit: we only check if the current block to be split is splittable, but not the target node. After this commit: if the current block is splittable but the current target node is not, we won't split the block but insert a <br> commit 4: [FIX] html_editor: properly fill inlineAncestors when formatting Before this commit: when the parent node of the current node is unsplittable, the `inlineAncestors` stays empty. After this commit: we handle this case and push the parent node in the list when the parent node is fully selected. We also add a fully selected predicate in link_plugin for the case when the selection includes all the content (except for zws) of a non-button link task-5244810 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#249294 Forward-Port-Of: odoo/odoo#241871