Monday, January 12, 2026
51 changes · saas-19.1
Resolved issues and error corrections
A bug was causing the timer to malfunction when switching between views with sample timesheet data. This update ensures all sample records have their timers paused, preventing data conflicts and improving the reliability of the timesheet display. This resolves a technical issue impacting user experience.
Original PR description
Steps to reproduce: - Open Timesheets app, - Click on search(magnifying lens) to open on cell with no records. - Let sample record be loaded. Issue: - Timer is already started. If you switch back to grid view and stop the time it throws traceback as it has data of sample records. Reason: - The sample records can have record states that are running. Fix: - Make sure all the sample records created have their timer paused using field `is_timer_running`. - Update condition in time display to check if time is running instead using `is_timer_running` not using `time_start` and `time_pause` as `time_pause` is not an active field. task-5267303 Forward-Port-Of: odoo/enterprise#102035
This update strengthens the security of our Point of Sale (POS) system by ensuring that data is accessed securely. Previously, unauthorized access attempts could cause errors and crashes. Now, the system checks permissions before reading POS data, preventing disruptions and improving stability.
Original PR description
**: pos_hr Before this commit: --- - POS data was read directly from records without validating read access. - This could raise `AccessError` when the user lacked permissions, breaking POS data loading. After this commit: --- - Check read access on records before calling `read`. - Prevent POS crashes caused by unauthorized model reads. runbot-231708 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226421
A recent issue preventing the completion of a key tour test for holiday allocation has been resolved. The problem stemmed from an empty leave type value causing form saving failures and timeouts. The fix ensures a valid leave type is always selected, guaranteeing the tour test runs successfully and accurately demonstrates the holiday allocation process.
Original PR description
Step to reproduce: - Install hr_holidays. - Run the time_off_allocation_warning_tour tour test. - The following error occurs: '(.o_form_readonly, .o_form_saved) has not been found. TIMEOUT: step failed to complete within 10000 ms'. Cause: - The leave type value is coming empty, causing the form to fail to save and resulting in a timeout. Fix: - Ensure holiday_status_id picks a valid leave type from selector. - Provide start dates and set the end dates to check the functionality. Task - 5264183 Forward-Port-Of: odoo/odoo#236639
This update resolves a technical issue within the HTML editor that could cause errors when content is completely removed after being inserted. The fix ensures the editor doesn't attempt to set a selection on a node that no longer exists in the DOM, improving stability and preventing unexpected errors. This primarily impacts the user experience when pasting and editing content.
Original PR description
During an `DomPlugin.insert`, the inserted content is added. Then some transformations are applied to clean up, including the removal of some nodes which are inventoried into `candidatesForRemoval`,…
During an `DomPlugin.insert`, the inserted content is added. Then some transformations are applied to clean up, including the removal of some nodes which are inventoried into `candidatesForRemoval`, and some specific `<br>` nodes. Ultimately, the selection is set after the last inserted node. In some cases, none of the inserted content remains after the clean up. When this happens, the selection is being set after the last inserted node, which is not part of the DOM anymore, and therefore leads to an error. This commit prevents this from happening by detecting when all inserted content was actually already removed. Steps to reproduce: - In a plain web page, copy a <br> into the clipboard - In an editor, put a character on a line - Paste => An error popup was displayed task-5429909 [FIX] html_editor: avoid failing when selection nodes are disconnected This commit addresses a traceback that was spotted but for which the actual scenario remains undetermined. The only possible way this traceback may occur is if nodes inside a selection are disconnected. The test added by this commit produces the same traceback as the observed one. task-5429909 Forward-Port-Of: odoo/odoo#242941 Forward-Port-Of: odoo/odoo#242488
This update corrects a bug that caused automatic balancing lines to be added to journal entries for company-paid expenses. The fix ensures that tax calculations are handled correctly when creating these expense reports, preventing inaccurate accounting entries. This improves the reliability of expense tracking for company-paid expenses.
Original PR description
Changing the analytic account on the journal entry generated by a company-paid expense creates an unwanted auto-balancing line. ## Steps to reproduce 1. Create an expense paid by the company. 2.…
Changing the analytic account on the journal entry generated by a company-paid expense creates an unwanted auto-balancing line. ## Steps to reproduce 1. Create an expense paid by the company. 2. Confirm and generate the expense report. 3. Reset the expense’s journal entry to draft and add an analytic account on the first line. → An auto-balancing line is added to the entry, and the remaining lines are incorrectly debited. ## Cause For company-paid expenses, the generated journal entry represents a *payment* rather than an *invoice*. In `_prepare_product_base_line_for_taxes_computation`, this causes the method to use `product_line_amount_currency` as the price unit, which excludes taxes. However, in `hr_expense`, the same method always defines `special_mode['total_included'] = False`. This combination leads `_get_tax_details` to call `_eval_tax_amount_price_included` instead of `_eval_tax_amount_price_excluded`, reapplying the tax on the lines. As a result, the move becomes unbalanced and Odoo generates an auto-balancing line to compensate. ## Solution Keep the special mode as *total excluded* for payments generated by company-paid expenses, since their tax and product lines are already handled separately in the corresponding `account.move`. **opw-5166707** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243052 Forward-Port-Of: odoo/odoo#233841
This update resolves an inconsistency in the SLSP reports by standardizing the order of data lines within the reports. Previously, test failures occurred due to varying data presentation. Adding a default order by clause to the SQL queries ensures a consistent and reliable report output.
Original PR description
A recent test was added that tests the lines of the SLSP reports. Up until now, all tests were either testing specific lines (not the report structure) or the export, which uses different queries. This new test is now failing inconsistently due to the order in which the data is being displayed. We add default orderby in SQL queries of the SLSP (using the models default orderby) in order to make the order consistent and avoid further issues.
This update fixes an issue where the barcode app on mobile devices displayed stock locations in a list view, which wasn't ideal for small screens. The change prioritizes a more user-friendly kanban view for mobile, ensuring product information is easily accessible on smaller devices.
Original PR description
Issue ===== On mobile, we should prioritize kanban views over list views because kanban views are usually more suitable for small device screen. That said, when a product's barcode is scanned in the Barcode app main menu, we show this product's stock locations but we do that with a list view, no matter if the user is on a big screen or a small screen. How to reproduce ================ On mobile device: - Enable location and have a product with a barcode and with quantities in two different locations; - Open Barcode app; - Scan the product's barcode => The product's stock locations are displayed in a list view, which is not very pratical on small device. Fix === The action key `mobile_view_mode` was not set, with this key, we can define what view type we want to prioritize for mobile device. [opw-5180783](https://www.odoo.com/odoo/project/49/tasks/5180783) Forward-Port-Of: odoo/enterprise#101957 Forward-Port-Of: odoo/enterprise#101336
This update resolves a bug where image styles (like width and transform) were incorrectly applied to new media types after an image was replaced. Now, styles are automatically cleared when switching between image and other media types, ensuring consistent and accurate media display.
Original PR description
**Current behavior before PR:** - When an image had styles applied to it (such as transform or width) and was replaced with another media type like an icon or document, those styles were incorrectly carried over to the replaced media. **Desired behavior after PR is merged:** - Since transform and width styles are meant to apply only to images, they are now removed when an image is replaced with other media types. task-5373362 Forward-Port-Of: odoo/odoo#240284 Forward-Port-Of: odoo/odoo#238319
This update fixes a potential issue where invoices generated from sales orders didn't always align with the correct fiscal partner information. Now, invoices use the invoice partner's details, ensuring consistent fiscal calculations across sales orders and their corresponding invoices. This improves accuracy and avoids discrepancies in financial reporting.
Original PR description
## Before this commit Fiscal position on Sale Orders was computed based on `partner_id` and `partner_shipping_id`. However, during invoice creation from a Sale Order, We uses `partner_invoice_id` as the invoice’s `partner_id`. This mismatch caused fiscal inconsistencies between the Sale Order and the generated Invoice in certain edge cases. ## After this commit Fiscal position is now computed using `partner_invoice_id` to ensure that both the Sale Order and its Invoice use the same fiscal partner reference. This aligns fiscal determination across documents and avoids inconsistencies in scenarios where the invoice partner differs from the order’s main or shipping partner. opw-5367523 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#239806
This update clarifies the call settings interface for users who have muted participants. Previously, the interface was confusing, showing the 'deafen' icon with the 'unmute' label. Now, only the 'undeafen' button is displayed when a participant is muted, providing a clearer and more intuitive experience.
Original PR description
Before this commit, the hint in the call settings was not taking into account if it was deafen or mute. On top of that the icon in the menu was showing the deafen icon but with the unmute label. When deafened, this was redundant with the undeafen button as well since unmute and undeafen are practically doing the same thing. Now, when deafen is activated, only the undeafen button is shown in the call menu and the hint in the call actions is undeafen not unmute. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242519
This update resolves issues that could lead to data inconsistencies when uninstalling the 'mail' module. Specifically, it ensures that model and field definitions are properly cleaned up during uninstallation and adds warnings to alert developers to potential problems with deleted records.
Original PR description
This fixes two overrides of `unlink()` that break when module `mail` is being uninstalled. It also fixes the uninstalling system to comply to the spec of the `ondelete` decorator. ### Add warnings…
This fixes two overrides of `unlink()` that break when module `mail` is being uninstalled.
It also fixes the uninstalling system to comply to the spec of the `ondelete` decorator.
### Add warnings when some model/field could not be deleted
The uninstallation process tries to delete all the records created by the modules being uninstalled. It uses a best-effort strategy, i.e., it skips the records that cannot be deleted, whatever the reason. But some records are very likely to cause problems, namely `ir.model` and `ir.model.fields` records, because skipping them implies not cleaning up their corresponding table's schema.
For instance, if a column is not dropped, reinstalling the corresponding module will possibly cause inconsistencies, because
- the column contains old values for existing records, which won't be recomputed (if the field is computed);
- the column contains NULLs for records created between the uninstallation and the reinstallation of the module.
We therefore add a warning in those cases, in order to detect and fix those potential issues as soon as possible.
### Make ondelete decorator work as documented
A method decorated with `@api.ondelete(at_uninstall=False)` should be called except when the method's module is being uninstalled. Currently the method is skipped when *any* module is uninstalled.
The fix consists in adding the set of modules being uninstalled in the attribute `registry.uninstalling_modules`, which may be used to detect uninstallation and determine which modules are being uninstalled.
### Replace MODULE_UNINSTALL_FLAG by new conventional flag 'force_delete'
We turn constant `MODULE_UNINSTALL_FLAG` into an explicit conventional flag, and rename it `force_delete` for the sake of simplicity. The idea is to decouple the flag from uninstallation. The caller simply uses
```py
records.with_context(force_delete=True).unlink()
```
to bypass some deletion hooks, which typically prevent deletion by raising some exception, in order to avoid data inconsistencies. On the callee's side, one has to explicitly detect the flag and skip the checks, like in:
```py
@api.ondelete(at_uninstall=False)
def _prevent_deleting_confirmed(self):
if self.env.context.get('force_delete'):
return
if any(record.state == 'confirm' for record in self):
raise UserError(_("You cannot delete confirmed records!"))
```
Note that the uninstallation process uses the convention by automatically adding `force_delete=True` in the `context` for deleting records.
### Fix issue module mail uninstallation
Two overrides of `unlink()` on models `ir.model` and `ir.model.fields` fail when uninstalling module "mail", because their code relies on some columns and those columns have been dropped already. This causes some table and column to remain after uninstallation. When reinstalling module "mail", errors like follows are logged:
```
column "mail_message_id" of relation "mail_tracking_value" contains null values
```
The fix consists in turning the overrides in proper "ondelete" methods, which are skipped when module "mail" is uninstalled.
https://github.com/odoo/enterprise/pull/103651This update resolves an issue that could cause errors during the removal of certain Odoo modules. The changes ensure that data is handled correctly when a module is deleted, preventing potential data loss or system instability. This improves the overall reliability of the Odoo Enterprise platform.
Original PR description
Companion of https://github.com/odoo/odoo/pull/242777
This update resolves an issue where pressing "Enter" in a form containing a Kanban-displayed x2many field would cause the system to crash. The fix ensures the Kanban renderer handles optional properties correctly, preventing errors and improving form stability. This ensures a smoother user experience when working with related records.
Original PR description
Be in a form view containing an x2many field displayed as a kanban view. Press "Enter". Before this commit, it crashed, because the kanban renderer tried to access it's `quickCreateState` props which was undefined. The props is indeed optional, so we must be careful when reading/using it. Issue introduced by https://github.com/odoo/odoo/pull/228632 Spotted by task~5441808 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures that all MOA (Monthly Accounting) values within the French accounting module are positive integers. Previously, the system could generate negative values, which caused errors. This change improves data accuracy and reliability for French tax reporting.
Original PR description
All MOA fields should be positive integer. task-5380637 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242976 Forward-Port-Of: odoo/odoo#239587
This update corrects a discrepancy in the calculation of employment bonuses for the Belgian payroll module (l10n_be_hr_payroll). The changes ensure bonus calculations are accurate up to March 2026, aligning with the latest tax regulations. This update maintains accurate financial reporting and compliance for businesses using this module.
Original PR description
Forward-Port-Of: odoo/enterprise#103820
This update fixes an issue where the timesheet timer wasn't correctly associated with the task being worked on. The fix ensures the timer uses the correct task or project from the list view, providing a more accurate and user-friendly timesheet experience. This prevents timesheets from being incorrectly linked to the user's favorite project.
Original PR description
### Issue: When looking at the list of timesheet for a task, we can start the time but the timer have default values that don't correspond to the task. ### Cause: `startTimer` in the `timesheetTimerService` is called from the timesheet timer hook without vals. It then makes an orm call to `action_start_new_timesheet_timer` to retrieve the fields (project or task) but as nothing is given in the vals, the selected project is the one returned by `_get_favorite_project_id()`. ### Solution: Get the context of the list view to retrieve the task or the project and input it in `vals`. opw-5342525 Forward-Port-Of: odoo/enterprise#102152
This update corrects a technical issue that prevented users from accessing bank accounts correctly when signing contracts within the HR module. The fix ensures a smooth and reliable process for managing contract signatures and associated banking permissions. This resolves a potential disruption to business operations.
Original PR description
Forward-Port-Of: odoo/enterprise#103807
This update resolves a bug impacting how absences are tracked within the HR Attendance module. The fix ensures accurate recording and reporting of employee absences, improving the reliability of attendance data. This change primarily affects the HR Attendance and HR Holidays Attendance modules.
Original PR description
Task: 5470030 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242567
This pull request addresses an issue with the way absences are managed within the HR Work Attendance module. The fix ensures accurate tracking and reporting of employee absences, improving the reliability of HR data. This update resolves a technical bug impacting the core functionality of this module.
Original PR description
Task: 5470030 Forward-Port-Of: odoo/enterprise#103781
This update resolves an issue where empty popups remained open and displayed incorrect options after content was removed. The fix ensures that popups are correctly closed when empty, preventing errors and improving the user experience. This improves the reliability of the website builder.
Original PR description
**Descripion of the problems** When the content of a popup is deleted, two problems happen: 1. The popup stays open displaying an empty white rectangle. 2. Options relative to the last removed…
**Descripion of the problems** When the content of a popup is deleted, two problems happen: 1. The popup stays open displaying an empty white rectangle. 2. Options relative to the last removed element are still displayed and produce an error if the user interacts with them. **How to reproduce** Drop the snippet `s_popup`, and remove the "Block" element. Problems: 1. the popup is still open but empty, 2. the "Block" options are still displayed. **Origin of the problems** Problem 1 happens simply because nothing takes care of removing empty popups. Problem 2 happens because `RemovePlugin.removeCurrentTarget` set the `nextTargetEl` without first checking if the element is activable or not. Thus, when removing the last block in a popup, the next target is set to the `.o_we_no_overlay` close button, despite it being not activable. As a result, when `BuilderOptionsPlugin.updateContainers` is called, it does not update containers because the target is not activable. Thus, the "Block" options are still displayed despite the element being removed. **Fix** Both problems are fixed by changing `RemovePlugin.isEmptyAndRemovable` such that empty popups are marked as removable. task-5401692 Forward-Port-Of: odoo/odoo#242377 Forward-Port-Of: odoo/odoo#239507
This update fixes minor inaccuracies in the German Point of Sale (POS) reporting process by ensuring the correct net value is used for pricing and by sending amounts as strings to the payment processor, Fiskaly. The changes also improve rounding precision to meet Fiskaly's requirements, and adjust order amounts for customer payments.
Original PR description
In this commit: ------------------ - Transferred **net value** instead of **gross value** for `price_per_unit`. - Included **cash statement business cases** that were prepared earlier but not sent to Fiskaly. - Ensured all **amount fields are sent as strings** to Fiskaly. - Fixed rounding precision using `toFixed()` to maintain **2–5 decimal places**, as required by Fiskaly (e.g., `4.70` should not become `4.7`). - Adjusted logic for **customer account payments** to send the **adjusted order amount** instead of the original total. task: 5122652 Forward-Port-Of: odoo/enterprise#99643
This update fixes an issue where refund alerts in the Point of Sale (POS) system could be triggered incorrectly due to rounding differences in order totals. The change ensures that the system accurately compares refund amounts against original order amounts, preventing false alerts and improving the reliability of the POS system. This update enhances the accuracy of financial reporting within the POS module.
Original PR description
Before this commit, if the total amount of the order had rounding differences compared to the sum of its lines, the system could incorrectly trigger an alert stating that the refund amount exceeds the original order amount. This was due to a direct comparison between the two amounts without considering potential rounding issues. opw-5402240 Forward-Port-Of: odoo/enterprise#103758 Forward-Port-Of: odoo/enterprise#102224
This update prevents users from creating new POS sessions when multiple online payment methods are linked to a single POS configuration. Previously, a workaround involving deleting payment methods was required. Now, a constraint ensures only one online payment method can be associated with a POS config, improving session stability.
Original PR description
Task: [#5420237](https://www.odoo.com/odoo/project/1737/tasks/5420237) --- There is a constraint on the `pos.config` model that prevents opening a POS session when multiple online payment methods are…
Task: [#5420237](https://www.odoo.com/odoo/project/1737/tasks/5420237) --- There is a constraint on the `pos.config` model that prevents opening a POS session when multiple online payment methods are configured for the same POS config. However, from the `pos.payment.method` model, it is still possible to add multiple online payment methods to a single POS config, which then prevents opening a session. In addition, if a session is already open, it is no longer possible to resolve the situation: * From `pos.payment.method`: the POS session must be closed before removing the POS config from an online payment method. * From `pos.config`: the payment methods field is read-only when there is an open session. We had to delete one of the online payment methods from the database directly to be able to open the POS session again. To prevent this inconsistent state, a constraint is added on `pos.payment.method` to ensure that each POS config has at most one online payment method. Forward-Port-Of: odoo/odoo#240343
This update addresses several issues impacting the accuracy of the social balance sheet calculations for Belgian payroll. Specifically, the system now correctly handles employees without certificates, avoids double-counting, and prevents incorrect gender checks on payslipless employees. These fixes ensure more reliable reporting for HR and accounting teams.
Original PR description
Forward-Port-Of: odoo/enterprise#103786
This update resolves a technical issue that caused warnings and potential crashes when searching for delayed production orders in the Manufacturing Orders list view. The change ensures the filter functions correctly and avoids future compatibility problems with Odoo's database system.
Original PR description
Issue before this commit: ========================= Searching for Delayed Productions in the MRP list view triggered: - A deprecation warning in saas-18.4 → 19.0: `warnings.warn("Since 19.0, use…
Issue before this commit:
=========================
Searching for Delayed Productions in the MRP list view triggered:
- A deprecation warning in saas-18.4 → 19.0:
`warnings.warn("Since 19.0, use Domain.custom(to_sql=lambda model, alias, query: SQL(...))", DeprecationWarning)`
- A traceback in master:
`Failed to cast TableSQL('mrp_production', -, None).date_finished into a datetime`
Steps to Reproduce:
=========================
- Install mrp module.
- Open the Manufacturing Orders list view.
- Filter by Delayed Productions.
- Observe the warning (saas-18.4 → 19.0) or traceback (master).
Cause of the issue:
=========================
Recent ORM changes in [PR](https://github.com/odoo/odoo/commit/f811af2c52df798b6ba0fc18e3f45944abdb7a12) disallow using raw SQL expressions as values inside normal domains.
Only Domain.custom() is permitted for injecting custom SQL.
The previous _search_is_delayed implementation used a deprecated pattern,
which caused the warning in current versions and a crash in the master version.
With This Commit:
=========================
- Rewrite the delayed production filter using Domain.custom() to safely generate the SQL.
- Preserve functional behaviour: the filter still returns delayed productions correctly.
- Avoid deprecation warnings and prevent traceback.
TaskID:- 5404547
Forward-Port-Of: odoo/odoo#243134
Forward-Port-Of: odoo/odoo#239574