Friday, January 16, 2026
15 changes · 18.0
Enhancements to existing features
This update enhances the testing process for invoice payments, specifically when using bank statement lines. A new test helper has been introduced to streamline and standardize these tests, ensuring more reliable payment processing scenarios. This improves the overall accuracy and stability of invoice payments.
Resolved issues and error corrections
This update resolves a technical error that prevented users in India from processing payments through Razorpay within the POS system. The issue stemmed from an attempt to use 'sudo' on a payment request object, which wasn't designed to support this function. This fix ensures smooth payment processing for Indian customers.
Original PR description
Steps: - Configure a Razorpay payment method in POS with Indian localization. - Open a POS session and process an order. - Start the Razorpay transaction. Issue: - An error pop-up is shown: 'RazorpayPosRequest' object has no attribute 'sudo'. Cause: - The code attempts to call sudo() on RazorpayPosRequest, which is not a model and does not support sudo. Fix: - Remove the unnecessary sudo() access from RazorpayPosRequest. Task-5501634
This update fixes a potential issue where location IDs could incorrectly identify related locations, leading to test failures. The change replaces a method of checking location hierarchy with a more reliable approach, ensuring accurate stock barcode processing. This resolves a build error and improves the stability of the stock module.
Original PR description
Previously, in the `_isSublocation`, to check if a location was a children of another location, we did that: ```javascript return childLocation.parent_path.includes(parentLocation.parent_path); ```…
Previously, in the `_isSublocation`, to check if a location was a children of another location, we did that: ```javascript return childLocation.parent_path.includes(parentLocation.parent_path); ``` The issue with that is, if locations' id are aligned, they can match even if they are not related. For example, imagine tested child location has ID 127 and the parent location has ID 7, we then check their `parent_path` (for example, '4/127/' for the child location and '7/' for the parent location), it can happen the child parent path can include the parent's parent path (in our example, '4/127/' includes '7/'.) To fix that, this commit replaces `includes` with `indexOf`, the result of the `indexOf` should always be 0 if the child location is indeed a sublocation of the parent location. Because of this issue, the second run of the tour `test_put_in_pack_new_lines` could sometime fail when the locations IDs are aligned. runbot build error: [233292](https://runbot.odoo.com/odoo/runbot.build.error/233292) Forward-Port-Of: odoo/enterprise#104350
This update fixes a bug that caused the survey session manager to fail when a question was deleted. The issue stemmed from incorrect data handling when a question was removed, leading to an error. This change ensures the session manager functions correctly even after questions are deleted, improving user experience.
Original PR description
Currently, an error occurs when opening the session manager after deleting a question. **Steps to reproduce:** - Install the `survey` module. - Create a `new survey`, add two questions, and click…
Currently, an error occurs when opening the session manager after deleting a question. **Steps to reproduce:** - Install the `survey` module. - Create a `new survey`, add two questions, and click `Create Live Session`. - Complete the survey and leave it on the `Thank You` page. - Switch back to the first tab, delete the second question, and click `Open Session Manager`. (Refer [this](https://drive.google.com/file/d/1_f7OwV6h2gWd-CluCYc7HpOXyDMIqGga/view?usp=sharing) for step to produce.) **Error:** `ValueError: False is not in list` **Root Cause:** At [1], the code assumes the `page_or_question` exists and tries to access `.index(page_or_question.id)`, but when the question has been deleted, `page_or_question.id` is `False`, causing an `error`. **Fix:** This commit prevents a crash when opening the session manager if the question was deleted. [1]: https://github.com/odoo/odoo/blob/ad03751ef0a9e617c2b24a30b1c06aa4e25d48a1/addons/survey/models/survey_survey.py#L810 sentry-5285798473
A bug was causing overdue invoices to appear twice in PDF follow-up reports. This update corrects a process error where invoices were incorrectly re-attached during report generation, ensuring invoices now appear only once in the final PDF. This improves the accuracy of follow-up reminders.
Original PR description
### Issue: In a manual follow-up printed as PDF, overdue invoices appear twice. ### Step to reproduce: - Create a partner and an overdue invoice for this partner, - Send the invoice, - go to this…
### Issue: In a manual follow-up printed as PDF, overdue invoices appear twice. ### Step to reproduce: - Create a partner and an overdue invoice for this partner, - Send the invoice, - go to this Partner then in the "Accounting" sheet, - Choose follow-up as manual, - Click on send, - In the wizard select Print and "Join invoices" ### Current behavior: The PDF display the reminder, the invoice, the report and the invoice again. ### Expected behavior: Invoice should appear only once in the follow-up PDF. ### Cause : When manually sending the follow-up, the wizard attaches the invoices to the follow-up. Then in `_get_followup_attachments`, it attaches the report, template attachments and the invoices again. In a manual follow up, it should be possible to choose which invoices are sent. The method `_get_invoices_to_print` ensure this by looking at the options' attachment. Therefore, it's not possible to clear the attachment field before fetching the invoices. opw-5368870
This update fixes a crash that occurred when Odoo users synced Google Calendar events with invalid timezone information. The system now gracefully handles invalid timezones by defaulting to UTC, preventing disruptions to the calendar sync process. This improves the reliability of Google Calendar integration.
Original PR description
- When users attempt to sync Google Calendar with Odoo, a crash occurs if the event’s timezone is invalid.
- In Sentry, we have observed multiple occurrences of this issue.
**Error: -**
`UnknownTimeZoneError: 'GMT+05:30'`
**Cause: -**
- At [1], we call `pytz.timezone` and if `self.event_tz` contains an invalid timezone string, `pytz` raises a time zone error, causing the sync to fail.
**Solution: -**
- Wrap the `pytz.timezone` call in a `try/except`.
- First, attempt with `self.event_tz or self.env.context.get('tz') or 'UTC'`.
- If that fails due to an invalid timezone, gracefully fall back to `UTC`.
[1]
https://github.com/odoo/odoo/blob/9805d09dff64de835de0c764da8c6e213d6b88aa/addons/calendar/models/calendar_recurrence.py#L513
**sentry-6738882905**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update resolves an issue where image saving in the HTML editor would fail due to missing data, often caused by browser extensions. The fix adds a validation step to ensure the image source exists before attempting to save, preventing a 'bool' object is not subscriptable' error.
Original PR description
Third-party extensions like ad blockers or image blockers might remove base64 encoded data from the frontend when an image is changed or when the page doesn’t load correctly using the `html_editor`.…
Third-party extensions like ad blockers or image blockers might remove base64 encoded data from the frontend when an image is changed or when the page doesn’t load correctly using the `html_editor`. In the video [1], this problem is shown by manually removing the base64 data for replication. It’s suspected that these common browser extensions could be causing the issue since this error has appeared in multiple databases. **Error:** `TypeError: 'bool' object is not subscriptable` **Root cause:** * Since data is `None` at [2], the checksum is not computed and remains `False` because [3] is not called. This leads to an error at [4] when attempting to index it. **Solution:** * Add an additional validation to check if the checksum exists. If it does not, set the image source to `False`. [1]: https://drive.google.com/file/d/1fC0HlvVKfkcAAit7UhQWDM9r4O3jMutF/view?usp=sharing [2]: https://github.com/odoo/odoo/blob/95ed5c75582631c7cc417b000569ff6451cc5006/addons/html_editor/controllers/main.py#L368 [3]: https://github.com/odoo/odoo/blob/95ed5c75582631c7cc417b000569ff6451cc5006/odoo/addons/base/models/ir_attachment.py#L280 [4]: https://github.com/odoo/odoo/blob/95ed5c75582631c7cc417b000569ff6451cc5006/addons/html_editor/models/ir_attachment.py#L54 sentry-6776476775
This update fixes a crash that occurred when loading demo employee data. The issue was caused by deleting the 'Administrative department' before attempting to load the demo data. The fix ensures that the system handles missing departments gracefully.
Original PR description
The system crash with error when user tries to load demo data of employees. **Steps to produce:-** - Install the `Attendances` module without demo data. - Navigate to `Employees > Departments` and…
The system crash with error when user tries to load demo data of employees.
**Steps to produce:-**
- Install the `Attendances` module without demo data.
- Navigate to `Employees > Departments` and **delete** the `Administrative department`.
- **Remove** all employees.
- Go to `Attendances > Load Demo`.
- Observe the error.
**Error:-**
```py
ValueError: External ID not found in the system: hr.dep_administration
ParseError: while parsing /home/odoo/src/odoo/saas-18.4/addons/hr/data/scenarios/hr_scenario.xml:126, somewhere inside <record id='employee_mw' model='hr.employee' forcecreate='1'>
<field name='active'>True</field>
<field name='name'>Michael Williams</field>
<field name='private_street'>349-943 Miania St.</field>
<field name='certificate'>master</field>
<field name='private_zip'>58198</field>
<field name='private_city'>Williston</field>
<field name='private_country_id' ref=base.us/>
<field name='private_phone'>+1 555-555-5757</field>
<field name='work_email'>williams@mycompany.example.com</field>
<field name='department_id' ref='hr.dep_administration'/>
<field name='job_id' ref='job_ceo'/>
<field name='job_title'>Chief Executive Officer</field>
<field name='company_id' ref='base.main_company'/>
<field name='category_ids' eval='[Command.set([ref('emplo...
```
- The error occurs because the user deleted the Administrative department, and then try to load data, that reference the deleted department.
- This commit resolves the error by providing a False value for the field if the employee department is missing.
**sentry-6856979884**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update prevents a potential error when refreshing YouTube access tokens. Previously, an empty response from the YouTube endpoint would cause a parsing error. The fix now gracefully handles empty responses by using an empty dictionary, ensuring the system continues to function correctly.
Original PR description
When refreshing the YouTube access token, the endpoint may return an empty response.
**Error:**
`JSONDecodeError - Expecting value: line 1 column 1 (char 0)`
**Cause:**
The method directly calls `.json()` on the response without validating whether the body is non-empty or valid JSON.
**Fix:**
This commit wraps the request handling in try/except and fall back to an empty dict (`{}`) when the response cannot be parsed as JSON.
sentry-6849711289This update resolves an issue where posting a tax return variant (like the Generic Tax Report) didn't consistently post its related grouped variant (e.g., Account > Tax). The fix ensures that both variants are properly processed when a closing entry is initiated, improving the reliability of tax reporting.
Original PR description
## Issue: When closing the entry for one tax return variant (e.g., the Generic Tax Report), the grouped variant (e.g., Account > Tax or Tax > Account) remains in draft, even though both variants represent the same content ## Cause: The function `_get_tax_closing_entries_for_closed_period()` searches for closing moves by `report_id` As a result, variants do not find the matching moves and instead generate a new `account.move` When the move is posted, it differs from the one of the other variant, so the existing move is never posted ## Steps to reproduce: - Create an invoice for any product with a 15% Tax (Invoice Date: 01/01/2025) - In Tax Return, select January 2025 - Click Closing Entry > Post - In Tax Return, change Report type to "Group by: Account > Tax" - Click Closing Entry, the move isn't posted opw-4858689
This update resolves an issue where tables inserted into the To-Do editor appeared after the existing text instead of before it. The fix streamlines the table insertion process, ensuring tables are placed correctly at the desired cursor position. This improves the user experience and prevents formatting inconsistencies.
Original PR description
### Steps to Reproduce : - Open To-Do and type some text. - Place the cursor at the start of the block. - Insert a table. (e.g.: /table) - The table appears after the text instead of before it. ### Purpose of this PR: - Table insertion logic was previously duplicated inside TablePlugin, where it tried to manually split text and inline nodes before inserting the table. However, this responsibility is now correctly handled by `DomPlugin.insert()`, which already: - deletes the current selection if needed. - splits text and inline nodes safely. - handles block boundaries and unsplittable elements. - normalizes the DOM after insertion. - places the cursor at a valid position. task-5480759 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where a warning about eTIMS configuration was incorrectly displayed on invoices for companies outside of Kenya. The fix ensures that eTIMS validation only applies to Kenyan companies, improving the user experience and preventing unnecessary alerts.
Original PR description
**Steps to reproduce:** * Install the **l10n_ke_edi_oscu** module. * Use a **non-Kenyan company** (e.g., “My Company (San Francisco)”). * Open any invoice for that company. **Observed behavior:** * A warning about **incomplete eTIMS configuration** is shown on invoices, even though the company is not based in Kenya. **Cause:** * The eTIMS validation logic runs for **all companies**. * Non-Kenyan companies, which do not require eTIMS setup, are still evaluated and trigger the warning. **Fix:** * Run the eTIMS validation only for **Kenyan companies**. * Suppress the warning for companies outside Kenya. opw-5435558
This update resolves an error that occurred when exporting SAFT reports for Austrian companies without defined contacts. The fix eliminates a redundant check, streamlining the process and preventing a traceback. This ensures SAFT exports function correctly for all Austrian businesses.
Original PR description
[FIX] l10n_at_saft: saft export traceback When no contacts is defined on the company and the user tries to download the SAFT to XML, a traceback is shown Steps to reproduce the traceback: - Install l10n_at_saft module and create an Austrian company with no contacts - Create a few invoices for this company - Open the General Ledger report and export SAFT to XML, the traceback should appear This fw port includes an other modification: the check 'missing_company_contact' was performed twice, one time in the account_saft module, and the second time in l10n_at_saft. So we removed it from the second module This check make sure the company partner has at least 1 child (1 contact) no-task Forward-Port-Of: odoo/enterprise#104144
This update corrects a data inconsistency in Odoo. Previously, Bulgaria was linked to the Bulgarian Lev (BGN). Now, with the adoption of the Euro on January 1, 2026, Bulgaria is correctly linked to the Euro (EUR) within Odoo's system. This ensures accurate financial reporting and data for businesses operating in Bulgaria.
Original PR description
Description of the issue/feature this PR addresses: Bulgaria adopted the euro as official currency as of 2026-01-01. Update the base country data accordingly. Current behavior before PR: In `res_country_data.xml`, Bulgaria is linked to BGN. Desired behavior after PR is merged: Bulgaria is linked to EUR in `res_country_data.xml`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241957
This update addresses several minor issues within the l10n_hr_edi module, primarily focused on improving the reliability and user experience of fiscal document processing and approval workflows. Specifically, it enhances error handling and clarifies settings related to multi-company operations, ensuring smoother and more accurate HR and accounting processes.
Original PR description
- Adjusting error handling for receiving an empty response from MER for a document fiscalization status. - Adding additional checks for running multi-company-wide MER API methods. - Adjusting how approval API call is handled when confirming a bill. - Adding a tooltip about Company BU in MER settings and missing "company dependent" indicators for the credentials. Continuation of task-4925745 Related to opw-5477846 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr