Friday, March 20, 2026
66 changes · saas-19.1
Resolved issues and error corrections
This update corrects a bug that was causing incorrect decimal values to be generated in French Intrastat XML reports. The issue stemmed from how the system processed invoice data, specifically when handling weights with decimal amounts. This fix ensures accurate reporting for French businesses using the Intrastat functionality.
Original PR description
Steps to reproduce: - Select a French company and activate intrastat - Create an invoice with a 100% discount to a european partner and provide intrastat values such as intrastat code, product commodity code, ... and most importantly a weight with a decimal amount. - Create at least one other invoice to a european partner that has a date earlier than the first one (but on the same month) - Go to intrastat report and export the XML (DEBWEB2) and select EMEBI and then Departures. -> Issue: The line that got processed after the one with a 0 value is not properly post-process regarding the integer conversion because we used to iterate on a list that was modified at the same time. opw-5973832 Forward-Port-Of: odoo/enterprise#110971
This update resolves a technical issue preventing the tour from functioning correctly within the Brazilian localization (l10n_br) module. The fix was necessary due to recent changes in the website's user interface, specifically related to the select menu, which caused a conflict and race conditions within the tour.
Original PR description
Because of the community PR that changes the DOM of the select menu, the tour in this commit crashed. This commit adapts the tour and fixes it as races conditions were still present part-of-task-5935511
This update resolves an error that occurred when creating payments for invoices using the Bacs Direct Debit method. The fix ensures that the system correctly handles scenarios where a company's bank account information is missing, preventing a validation error and ensuring payment processing works as expected.
Original PR description
Currently, an error occurs when user creates a payment for an invoice. **Steps to Reproduce:** - Install `l10n_uk_bacs` with demo data. - Switch to the `UK company`. - Go to `Journals`, select the…
Currently, an error occurs when user creates a payment for an invoice. **Steps to Reproduce:** - Install `l10n_uk_bacs` with demo data. - Switch to the `UK company`. - Go to `Journals`, select the `Bank Journal`, and remove the `Bank Account Number`. - Go to `Invoices` and create an invoice by adding an `invoice line` with price greater than zero. - `Confirm` the invoice. - Click `Pay`, select `Bacs Direct Debit` as the payment method, and click `Create Payment`. `ValueError: Expected singleton: res.partner.bank()` This error occurs when creating a payment for an invoice using the Bacs Direct Debit payment method. The constraint check bacs bank account trigger [1], but since the journal has no bank account number, it raises an error here [2]. Similar error also occurs when validating a batch payment [3]. This commit ensures that if the journal has no bank account, or if the bank account is invalid, the system raises the same validation error. In batch mode, it raises a UserError when the account is missing. [1]: https://github.com/odoo/enterprise/blob/8405155aa94b4f26efb202cbf815e874375a7f49/l10n_uk_bacs/models/account_payment.py#L52-L58 [2]: https://github.com/odoo/enterprise/blob/8405155aa94b4f26efb202cbf815e874375a7f49/l10n_uk_bacs/models/res_partner_bank.py#L18-L19 [3]: https://github.com/odoo/enterprise/blob/8405155aa94b4f26efb202cbf815e874375a7f49/l10n_uk_bacs/models/account_batch_payment.py#L74 sentry-7259107152
This update resolves a bug where subscriptions would incorrectly revert to an 'In Progress' state after a credit note payment was processed. The fix prevents the reopening of subscriptions when a credit note payment (specifically refunds) is made, ensuring subscription status accurately reflects the payment cycle. This improves subscription management and prevents disruptions.
Original PR description
Steps to reproduce: ------------------------------ 1. Install Subscription module 2. Create a new subscription and confirm it 3. Create an invoice from the subscription. * Register a payment and…
Steps to reproduce: ------------------------------ 1. Install Subscription module 2. Create a new subscription and confirm it 3. Create an invoice from the subscription. * Register a payment and ensure the invoice is in the Paid state. 4. Go back to the subscription and close it with any reason 5. Open the related invoice. * Create and Confirm Credit Note. * Register a payment for the credit note. 6. Go back to subscription Observation: ------------------------------ The subscription is automatically set back to `In Progress` even though it was previously churned. Issue: ------------------------------ The method `_reopen_paid_churned_subscription` reopens churned subscriptions when an invoice is set to `in_payment` or `paid`. There was no check to exclude refund moves (`move_type = 'out_refund'`), causing the subscription to be reopened when a credit note is paid. Solution: ------------------------------ Add a condition to exclude refund invoices from the reopening logic opw-5947999 Forward-Port-Of: odoo/enterprise#108487
This update fixes an issue where multiple email addresses on a contact were being overwritten when creating a helpdesk ticket. The change ensures that all email addresses associated with a contact are correctly captured, improving the reliability of ticket creation. This resolves a potential data loss scenario.
Original PR description
Prerequisites: ------------------------------ 1. Set up incoming mail server with Create a New Record set to Helpdesk Ticket 2. From Settings, create one Alias Domain Steps to reproduce:…
Prerequisites: ------------------------------ 1. Set up incoming mail server with Create a New Record set to Helpdesk Ticket 2. From Settings, create one Alias Domain Steps to reproduce: ------------------------------ 1. Install Helpdesk module 2. Open Helpdesk Team > Settings 3. Inside Channels, Set the mail used for the incoming server and the alias created 4. Set Accept Emails From to Everyone 5. Create a new contact with multiple emails (eg: `a@b.com`, `c@d.com`) 6. From Fiest mail (eg: `a@b.com`), Send one mail to mail set in the helpdesk team alias mail. 7. Open Incoming mail sever > Click on Fetch Now 8. Open Created Contact Observation: ------------------------------ The contact's email field is overwritten. The second email address (e.g. `c@d.com`) is lost Issue: ------------------------------ After `create`, since `partner_email` was stored with a value that differs from `partner_id.email`, the inverse method `_inverse_partner_email` kicks in. This is where `_get_partner_email_update()` is called. In `_get_partner_email_update()` `tools.email_normalize()` only handles a single email. When the partner has multiple email, the normalization keeps both, while the ticket email normalizes to just have one mail. The strict `!=` comparison fails, triggering the unwanted update. https://github.com/odoo/enterprise/blob/7c23efafe368787c858db31cec075f642ae6715b/helpdesk/models/helpdesk_ticket.py#L363-L369 Solution: ------------------------------ Instead of comparing the full normalized strings, we should check whether the ticket's normalized email is contained within the set of the partner's normalized emails Note for reviewer ----------------------------- After discussion with the PO (LNA), his opinion is that having multiple email addresses in a single field is not a good practice. This use case is only semi-supported in Odoo, it may work in some cases, but it is not reliable. The recommended approach is to create separate contacts for each email address. That said, we should also avoid automatically clearing or altering the existing value in the field. Based on this, I have implemented a minimal fix that prevents altering the existing value in the field. I am leaving it up to the review to decide whether this fix is worth keeping from a technical standpoint. opw-5478067 Forward-Port-Of: odoo/enterprise#107808
This update resolves an issue where GS1 barcode filtering would fail due to an incorrect date interpretation. The fix prevents errors from blocking product filtering, ensuring accurate internal transfer operations. This improves the reliability of our inventory management system.
Original PR description
Steps to reproduce: - Activate the GS1 nomenclature - Create a product "P1" with the barcode: 15099590225865 - Create an internal transfer with one unit of P1 - Go to Barcode > Operations > Internal…
Steps to reproduce: - Activate the GS1 nomenclature - Create a product "P1" with the barcode: 15099590225865 - Create an internal transfer with one unit of P1 - Go to Barcode > Operations > Internal Transfers - Scan the barcode: 15099590225865 to filter transfers by this product barcode Problem: An validation error is raised: A ValidationError is raised: "A GS1 barcode nomenclature pattern was matched. However, the barcode failed to be converted to a valid date." Explanation: GS1 barcodes must follow a strict nomenclature based on well-defined rules. For example, a GS1 product barcode should start with the Application Identifier 01 followed by 14 digits. The GS1 parser processes the barcode rule by rule and applies the first matching rule. In this case, the barcode 15099590483921 is interpreted as a date because it starts with "15", which corresponds to a GS1 Application Identifier for a date. As a result, the parser attempts to convert the first six digits into a date and raises a ValidationError. Solution: Catch the ValidationError raised during GS1 date parsing in filter_on_barcode and explicitly reset parsed_results to False, allowing the normal filter on product resolution logic to continue. This prevents GS1 parsing errors from blocking valid barcodes and ensures that product is correctly filtered opw-5929064 Forward-Port-Of: odoo/enterprise#110679 Forward-Port-Of: odoo/enterprise#110636
This update fixes an issue where subscription products weren't displaying prices with tax, even when the website setting was enabled to show tax-inclusive prices. The fix ensures that the correct tax rates are applied based on the customer's company, resolving a discrepancy in how product company IDs were being evaluated. This ensures accurate pricing for all subscription customers.
Original PR description
subscriptions Despite enabling the website setting to display tax-inclusive prices, subscription products show prices without tax when a recurring pricelist is configured. In `_get_sales_prices`, the product’s company ID is compared to the website’s company, but products visible to all have a false company ID, and products assigned to a parent company retain the parent’s company ID. As a result, when the product’s company ID does not match the website’s company ID, no taxes are applied.Instead, _filter_taxes_by_company should be used to determine whether the company can access the product’s tax_id. opw-5222411 Forward-Port-Of: odoo/enterprise#102102 Forward-Port-Of: odoo/enterprise#100662
This update resolves a problem where incorrect invoice folio numbers (starting with negative signs) were being generated when no Chilean Fiscal Authorization File (CAF) was configured. The fix ensures that folios are correctly generated based on available CAF numbers, preventing sequence corruption and costly database retries. This improves invoice accuracy and stability for Chilean users.
Original PR description
`l10n_cl_edi` overrides `account.move._get_last_sequence()` to ensure the folio belongs to an available in-use CAF. When no CAF exists at all, `l10n_latam.document.type._get_start_number()` returns 0 and the fallback builds a previous sequence using start_nb - 1. Formatting -1 as `:06d` yields “-00001”, which then propagates to “FAC -00002”, “-00003” and corrupts the sequence chain. In addition, returning an invalid “last sequence” may force `sequence.mixin` to search for a free number under the UNIQUE constraint by retrying increments inside a savepoint and rolling back on UniqueViolation, which is costly when many values are already taken see [ _locked_increment()](https://github.com/odoo/odoo/blob/18.0/addons/account/models/sequence_mixin.py#L352). Now we only reset to the CAF start when an in-use CAF actually exists (start_nb > 0). opw-5918758 Forward-Port-Of: odoo/enterprise#108909
This update resolves a technical issue that caused a traceback when using the pivot table autofill feature. The fix corrects a misidentification of the function being called, ensuring consistent behavior with vertical autofills. While the core autofill functionality remains unchanged, this resolves a potential error.
Original PR description
When autofilling a positional pivot row header horizontally, we would get a traceback because we were calling `_autofillPivotColHeader` instead of `_autofillPivotRowHeader`. Note that this fix only fixes the traceback, the result is not correct, but is consistent with autofilling a positional col header vertically. Task: [5909266](https://www.odoo.com/odoo/2328/tasks/5909266) Forward-Port-Of: odoo/enterprise#110994 Forward-Port-Of: odoo/enterprise#109620
This update optimizes the database by removing unnecessary default values from company and partner records. This change reduces data storage and improves performance, particularly for businesses managing multiple companies with different fiscal settings. The fix also resolves a previous issue causing cron jobs to fail.
Original PR description
On multi-company databases, having the defaults value on res.partner fields can unnecessary bloat the database for other companies with different fiscal package (localization). This commit remove the `l10n_ke_branch_code` field default on `res.partner` - the related field on `res.company` has been converted to a stored-compute + inverse so that partner related to a company automatically get the default value `00` whithout needing to touch other partner records. The `l10n_ke_oscu_last_fetch_purchase_date` default on `res.company` has also been removed, cron already fallback to the same default value when none are provided and will update it anyway after it ran. opw-5220129 Forward-Port-Of: odoo/enterprise#105917
This update resolves an issue where generating financial reports (FAIA) for Luxembourg companies using multi-currency vendor bills resulted in errors. The fix ensures the necessary currency information is included in the report template, allowing for accurate reporting of sales and purchase taxes. This improves the reliability of financial data for Luxembourg businesses.
Original PR description
Steps to reproduce 1/ setup a LU company. The default company currency will be EUR. 2/ create a vendor bill in another currecy (e.g. USD) 3/ take note of the bill date and accounting date (ideally set them in the past, like 1 month) 4/ generate the FAIA report for the period containing the created bill => error while rendering the qweb template The core of the error is when rendering the l10n_lu saft template. Sales invoices and purchase invoices reuse the standard `account_saft.tax_information` report, which expects to find `currency_code` in the object's fields. This commit explicitly re-adds it when creating the document's tax summary. opw-5216057 Forward-Port-Of: odoo/enterprise#110660 Forward-Port-Of: odoo/enterprise#106902
This update resolves an issue where payrun calculations were failing when an employee's contract started mid-period. The fix ensures accurate integration factor calculations for new hires with staggered contract start dates, preventing incomplete payrun generation. This improves payroll accuracy for new employees.
Original PR description
An error is thrown when an employee's contract starts mid-period. ```py Invalid Operation Wrong python code defined for: - Employee: Cesar Osbaldo Cruz Solorzano - Version: False - Payslip: Payslip -…
An error is thrown when an employee's contract starts mid-period.
```py
Invalid Operation
Wrong python code defined for:
- Employee: Cesar Osbaldo Cruz Solorzano
- Version: False
- Payslip: Payslip - Cesar Osbaldo Cruz Solorzano - 01/16/2026 - 01/31/2026
- Salary rule: Integrated Daily Wage (Base) (INT_DAY_WAGE_BASE)
- Error: AttributeError("'bool' object has no attribute 'year'") while evaluating
'\nresult = round(payslip.l10n_mx_integration_factor * payslip.l10n_mx_daily_salary, 4)\n
```
Steps to reproduce:
1. Install `l10n_mx_hr_payroll` modules
2. Switch to ESCUELA KEMPER URGATE company
3. Go to Employees and open Cesar Osbaldo Cruz Solorzano
4. Go to Payroll tab, change the start date of contract to 01/10/2026 and save
5. Go to Payroll > Payslips > Payslips and create a new pay run
6. Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Monthly' and Period '01/01/2026 -> 01/31/2026'
7. Click on Continue, select Cesar and click on Select
8. An error is thrown
Problem:
In `_compute_integration_factor` method, `_get_first_contract_date` is called with context `before_date`, it returns `False` as the contract starts after the payslip period. This causes an error when trying to access the `year` field of `start_date`.
Solution:
Add a fallback to call `_get_first_contract_date` without context in case the first call returns `False`.
target: saas-18.4
task-6034836
Forward-Port-Of: odoo/enterprise#110568This update resolves a visual issue where the map view in the "My Dashboard" sometimes collapsed. The fix removes conflicting height settings and adds a minimum height to ensure the map always displays correctly, regardless of the number of records shown.
Original PR description
This commit fixes rendering height issues when the map view is displayed inside "My Dashboard". * Removed `height: 100%` from the map and pin list containers. This conflicting rule interfered with the flexbox layout, often causing the map to collapse entirely since it couldn't compute its own height. * Added a `min-height` to the map renderer. This ensures the map always occupies a reasonable amount of space in the dashboard, even when there are few or no records to display. task-6022958 Forward-Port-Of: odoo/enterprise#110968 Forward-Port-Of: odoo/enterprise#110790
This update resolves an issue where the bulk payments feature would crash if a bank journal wasn't properly connected. A new user message has been added to alert users when a journal isn't linked to a bank, preventing the error and improving the user experience.
Original PR description
This commit: https://github.com/odoo/enterprise/commit/c9cc89f58f7d98396afac3bdacfeff9b00a02a21 introduce the initiate bulk payments feature. When selecting a batch you can also check the status of this batch. But for the moment, if you select a batch that is not connected to a bank, the action will traceback with a redirect. This commit will add a user error to warn the user than the journal needs to be connected to a bank. task-6009083 Forward-Port-Of: odoo/enterprise#111031 Forward-Port-Of: odoo/enterprise#109956
This update ensures that the tax returns journal is automatically translated into all supported languages, rather than just the user's language. This improves the accuracy and usability of the tax reporting feature for international users.
Original PR description
Currently, the tax returns journal is created in the code and not via the standard `@template` function that makes sure it is always translated in the installed languages. So for now it was only translated in language of the current user. We refactored the code so the journal gets created via the standard `@template` function and thus automatically gets translated into all the installed languages. task-5921458 Forward-Port-Of: odoo/enterprise#111126 Forward-Port-Of: odoo/enterprise#107465
This update corrects a bug in the demo data for our Odoo Enterprise system. Specifically, it ensures that leave allocations are correctly created when using 'faketime,' which simulates future dates. This prevents errors related to time off calculations and ensures accurate reporting for all users.
Original PR description
Issue: The Anita Oliver contract starts on %Y-01-01, so her leave allocation begins from that date. When running with faketime set to 2027-01-01, the system attempts to create leave for the previous month, which results in an error stating that there is no allocation for that time off. Fix: Update the demo data to create the leave and payslip for the first month of the year. This prevents failures when using faketime and ensures it works correctly for real usage of `time off to defer`. task-6026690
This update corrects a potential issue where calculations for employee payslips were unintentionally impacting a large number of records. The change now limits the calculation to active payslips, ensuring accurate and reliable payroll processing. This improves data integrity and reduces the risk of errors.
Original PR description
Before this commit, `_compute_basic_net` was not limited to specific payslips, potentially affecting thousands of records and even more of `hr.payslip.line` records. This commit restricts the compute to ongoing payslips. task-6022499 Forward-Port-Of: odoo/enterprise#110069
This update resolves an issue preventing new employee creation when generating BVG-LLP reports. The fix addresses a technical problem with how Odoo compares report data, ensuring the system correctly handles multiple reports with the same month.
Original PR description
Steps to reproduce: ---------------------------------- 1. Install `l10n_ch_hr_payroll_elm_transmission` module 2. Switch to Swiss company 3. Navigate to Payroll > Transmission > BVG-LLP Basis…
Steps to reproduce:
----------------------------------
1. Install `l10n_ch_hr_payroll_elm_transmission` module
2. Switch to Swiss company
3. Navigate to Payroll > Transmission > BVG-LLP Basis Declaration
4. Create two Reports with same Year and Month
5. Now try to create new Employee from the employee app
Observation:
----------------------------------
Tracaback Occurs:
```
File '/home/odoo/src/enterprise/19.0/l10n_ch_hr_payroll/models/l10n_ch_employee_monthly_values.py', line 319, in _compute_bvg_lpp_annual_basis
existing_declaration = max(existing_declaration, key=lambda r: r.month) if existing_declaration else False
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File '/home/odoo/src/odoo/19.0/odoo/orm/models.py', line 5934, in ensure_one
raise ValueError('Expected singleton: %s' % self)
ValueError: Expected singleton: l10n.ch.lpp.basis.report(1, 2)
```
Issue:
----------------------------------
In the following code:
https://github.com/odoo/enterprise/blob/44a26539093f9313d9cd5f823c11866e3c98ec97/l10n_ch_hr_payroll_elm_transmission/models/l10n_ch_employee_monthly_values.py#L319-L320
Python's max() function doesn't just call the key function once per item. When there are ties (equal key values), it may need to compare the original objects, and during this process, Odoo's recordset operations combine records, causing the lambda receives `r` as a combined recordset. To access `.month` on a multi-record recordset it gives singleton error.
Solution:
----------------------------------
Creates tuples of (month, recordset) pairs and uses max() to compare month integers directly, avoiding the singleton error.
opw-5391742
Forward-Port-Of: odoo/enterprise#111084
Forward-Port-Of: odoo/enterprise#102335This update resolves a potential issue where the system couldn't correctly evaluate data within project tasks. The fix ensures that all data used in evaluation processes are treated as strings, preventing errors and improving data integrity. This ensures reliable operation of the industry_fsm module.
Original PR description
literal_eval needs string values to evaluate,
action.get('domain', []) returns non-string value.
Forward-Port-Of: odoo/enterprise#111202This update corrects a problem in the GSTR report testing process. Previously, tests were deleting tax lines, which caused inaccurate reporting. Now, the system correctly removes taxes from the account move line, ensuring accurate GSTR report calculations and compliance.
Original PR description
Before this PR: - A test case was deleting taxes. After this PR: - Removed the taxes from the account move line instead of deleting the taxes. Related PR: https://github.com/odoo/odoo/pull/245243 task-5472834 Forward-Port-Of: odoo/enterprise#111198 Forward-Port-Of: odoo/enterprise#105174
This update corrects an issue with the numbering of report lines within the Vietnamese balance sheet report. Specifically, the order of items under 'I. Short-term liabilities' was adjusted for improved clarity and accuracy. This ensures the report aligns with Vietnamese accounting standards.
Original PR description
- Fixed the numbering of report lines under the section "I. Short-term liabilities" in the balance sheet report 6035762 Forward-Port-Of: odoo/enterprise#111234
This update corrects a technical issue where Helpdesk ticket buttons weren't being properly recognized by the system's editor. The change ensures buttons within email templates function correctly, preventing links from appearing as buttons. This improves the user experience when interacting with tickets.
Original PR description
Without the `btn` class, buttons are identified as links by the editor. This commit adjusts the buttons inside the mail templates so that they are properly handled by the editor. Steps to reproduce: - Have demo data - Turn on developer mode - Go to Helpdesk > Customer Care - Open ticket "Where can I download a catalog?" - In the debug menu, go to Messages - Open the first template - Click on the "View Ticket" button - Edit the link => The link popover recognized it as a link instead of a button. As of saas-18.2, the style is replaced by a plain link style when changing the URL. task-5948539 Forward-Port-Of: odoo/enterprise#110797 Forward-Port-Of: odoo/enterprise#107888
This update fixes an issue in the Spanish (ES) balance sheet reports where retained earnings were incorrectly excluded. Now, all relevant equity adjustments are accurately reflected, ensuring consistent and reliable equity totals. This improves the accuracy of financial reporting for Spanish businesses using Odoo Enterprise.
Original PR description
Description of the issue this commit addresses: The ES balance sheet “prior periods” line only matched code 12, so retained/unaffected earnings posted on other codes were skipped, which could understate or skew equity totals. --- Desired behavior after this commit is merged: The line now includes both accounts with code 12% and accounts of type equity_unaffected, so carried-forward results are always included and equity totals stay consistent. --- task-6047627 Forward-Port-Of: odoo/enterprise#111249
This update corrects a visual discrepancy in the AI Live Chat snippet's appearance, ensuring it matches how it's displayed in real-time. The issue stemmed from mismatched code structures, and this fix ensures a consistent user experience across different devices and configurations. It also resolves a related problem with the fallback button visibility.
Original PR description
Scenario: - add ai livechat snippet block - switch to mobile - enable "Fallback Button" - save Result: the rendering is different between edition and real usage of AI livechat snippet. Cause: structure and classes don't match Fix: make the structure and classes match. opw-5458575 pr note: I copied `ai_website_livechat.AILivechatComponent` in `ai_website_livechat.s_ai_livechat_edit` but it might make more sense to just render the owl widget with a class that neuter the AI (this way we don't need to update both template at each change) Forward-Port-Of: odoo/enterprise#109569
This update corrects a technical issue where archived partner data was incorrectly being matched during bank statement retrieval. Now, the system only considers active partners when finding bank statements, ensuring accurate partner assignments and data integrity. This improves the reliability of financial reporting.
Original PR description
Description of the issue this commit addresses: Partner auto-detection on statement lines could match archived partners via SQL causing unexpected partner_id assignment. Desired behavior after this commit is merged: Partner retrieval from bank account, partner name, and previous statement lines only considers active partners, preventing archived matches. runbot-238918 Forward-Port-Of: odoo/enterprise#111029 Forward-Port-Of: odoo/enterprise#110446