Wednesday, April 29, 2026
50 changes · saas-19.1
Resolved issues and error corrections
This update corrects a technical issue preventing proper export of Hong Kong payroll XML files to the IRD platform. The fix ensures the correct file encoding and format (including a required BOM) are used, resolving a compatibility problem. This ensures accurate data transmission for tax reporting.
Original PR description
Following recent tests, we noticed that the encoding used when exporting our XML files doesn't follow the required format. We noticed two issues during testing: - The IRD platform expects the file to have BOM included. - The encoding in the header must be capitalized. We solve this in this commit by prepending the BOM bytes to the xml bytes; and making sure to capitalize the URF-8 in the header. task-6150470 --- Note: There will be a lot to do during forward ports, as these have changed quite a bit. (XML support for the other file types, and a proper testing file, at least) Forward-Port-Of: odoo/enterprise#115227
This update ensures that when a company is quickly created through the equity module, the system correctly identifies it as a company. Previously, this wasn't happening, leading to incorrect data. The fix also includes a minor correction to view strings.
Original PR description
The partner_id field on all equity models represents a company. Therefore, quick-creating a partner_id should create it with is_company set to True. However, that wasn't the case. This commit fixes this issue by making sure that partner_id when quick-created in equity models has is_company set to True. It also fixes a typo in the string attribute of valuation list and form views. task-6132343 Forward-Port-Of: odoo/enterprise#114375
This update fixes an issue where unreconciling batch payments could unexpectedly revert vendor invoices to draft due to approval checks. The change allows for a necessary repost to complete the reconciliation process, even when third-party approval workflows are in place. This prevents users from needing to manually re-enter data.
Original PR description
When unreconciling a batch payment from a bank statement line, delete_reconciled_line() resets the linked invoice to draft to recompute its amount_residual, then re-posts it. If a third-party module…
When unreconciling a batch payment from a bank statement line, delete_reconciled_line() resets the linked invoice to draft to recompute its amount_residual, then re-posts it. If a third-party module (e.g. Studio Approvals) silently rejects action_post for the current user, the invoice stays in draft and the user has to redo the work manually. This internal repost is not a business action, the move was already approved when initially posted, so it can run as sudo to bypass approval checks. Steps to reproduce: 1. Add a Studio Approval rule on account.move.action_post with an approver other than the current user 2. As a user without that approval right, post a vendor bill and register a payment 3. Add the payment to a batch payment 4. Reconcile a bank statement line with the batch payment 5. With the user without approval rights, try to unreconcile the bank statement line (delete_reconciled_line) - Expected: the bill stays Posted. - Actual (before fix): the bill silently rolls back to Draft because action_post is rejected by the approval hook. opw-6121448 Forward-Port-Of: odoo/enterprise#115241
This update resolves an issue preventing kiosks from correctly communicating with new IoT box images. The fix ensures the correct message format is used, allowing the IoT box to process data properly. This improves the functionality of kiosks connected to the new IoT box infrastructure.
Original PR description
The new IoT box images expect the websocket messages to contain just `iot_identifier` and `device_identifier` instead of a list of `iot_identifiers` and `device_identifiers`. This method that the kiosk calls to send a message to the blackbox was not updated, causing the IoT box to ignore the message. This commit fixes the issue by adding the `iot_identifier` and `device_identifier` to the message. Forward-Port-Of: odoo/enterprise#115497
This update corrects a technical issue where styling applied to list views was incorrectly affecting other views within the account reports module. The fix ensures that styling is applied only to the intended list views, improving the visual consistency of the reporting interface. This resolves a minor cosmetic problem.
Original PR description
The css selector used to add the small border at the start of the line. So it end-up being applied in other view as well. task-6141685 Forward-Port-Of: odoo/enterprise#114903
This update resolves an issue where livechat channels with AI agents were not appearing correctly. The fix corrects a coding error that was preventing the system from accurately counting agents associated with each channel. This ensures all livechat channels, including those utilizing AI, are visible to users.
Original PR description
The number of agents linked to a livechat channel was always 0 because of a mistake in the code. This prevented livechat channels with AI agents from appearing to users. This commit fixes the problem. task-5409200 Forward-Port-Of: odoo/enterprise#111574
This update resolves a bug where pasting a list item directly into the HTML editor would cause the main content area of the application to disappear after saving. The fix ensures that newly pasted list items are correctly wrapped within a list container, preventing the browser from incorrectly removing surrounding elements.
Original PR description
Problem: Pasting a `<li>` element inside a header block caused `<main>` and `<footer>` to disappear after saving. The browser's HTML parser ejects everything following an orphaned `<li>` (one without a `<ul>`/`<ol>` parent) out of its ancestor tree. Cause: The root cause was `closestElement(selection.anchorNode, listElementSelector)` finding a `<ul>`/`<ol>` ancestor that was not a direct parent of the insertion point, resulting in a `<li>` being inserted without a wrapping list element. Steps to reproduce: - Copy a `<li>` element and paste it in the Text Element in the header. - Save - `<main>` content disappears from the page. opw-6113857 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260320
This update resolves a layout problem in the Safaricom POS payment method configuration form. The previous design caused the right column to disappear, making it difficult for users to set up payment terminals. The fix simplifies the view structure, ensuring the form displays correctly and functions as intended.
Original PR description
The nested `group` elements in the `pos_payment_method_views.xml` view in `pos_safaricom` caused the layout of the form to break when the module is installed. More specifically, the entire right…
The nested `group` elements in the `pos_payment_method_views.xml` view in `pos_safaricom` caused the layout of the form to break when the module is installed. More specifically, the entire right column of the form loses all the field labels, making it very difficult to fill out the information to configure a payment terminal. This commit fixes the issue by removing the `group` elements from the view, instead just using the `field` elements directly as is done in other payment terminal modules. Before (Safaricom selected): <img width="678" height="504" alt="image" src="https://github.com/user-attachments/assets/9c41643f-1a98-4e44-9493-f0e6e8161a50" /> Before (Viva selected): <img width="674" height="371" alt="image" src="https://github.com/user-attachments/assets/409f5c7a-da13-4f90-8145-a1ed5d6bbf7f" /> After (Safaricom selected): <img width="674" height="531" alt="image" src="https://github.com/user-attachments/assets/a3118563-39a3-4c41-a807-296e531abe58" /> After (Viva selected): <img width="665" height="447" alt="image" src="https://github.com/user-attachments/assets/51140a28-1fca-4d94-a81e-d45e081024a2" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261746
This update addresses a visual glitch in the composer where applying a list alignment option would sometimes cause a brief flicker and fail to apply correctly. The fix prevents a 'blur' event from triggering unnecessary DOM duplication, ensuring list alignment works reliably the first time.
Original PR description
Problem: When the chatter is open and text is selected, applying a list from the toolbar causes a flicker, and the list is sometimes not applied on the first attempt. Cause: Opening the list dropdown triggers a `blur` event on the `html_editor` field, which calls `getInlinedEditorContent` and duplicates the DOM to perform inlining. This unnecessary processing causes the visual flicker and may interrupt the list application. Solution: Prevent the field from blurring when selecting a list alignment option from the toolbar. Steps to reproduce: - Open a new record. - Open the composer. - Add text and select it. - Apply a list using the toolbar. - Observe that sometimes the list is not applied on the first try and the content briefly flickers. opw-6153261 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261476
This update resolves an issue where invoices generated with the l10n_sa and l10n_sa_edi modules were displaying a duplicate tax number. The change ensures that company details now print the tax number only once, improving invoice accuracy and presentation. This was triggered by a previous update.
Original PR description
Before this change: - the additional_company_details would print a second tax number to invoice printout in l10n_sa After this change: - company details will print tax number only once Forward-Port-Of: odoo/odoo#261272
This update resolves an issue in the Bangladesh localization where an incorrect expense account was being automatically applied to inventory valuations. Removing this forced setting ensures that inventory accounting aligns with standard Bangladesh regulations and avoids unexpected stock variations.
Original PR description
Issue: The Bangladesh chart template sets account_stock_expense_id on the inventory valuation account. This triggers Stock Variation entries following perpetual continental behavior, which is not expected for Bangladesh localization. Cause: l10n_bd template data explicitly populated `account_stock_expense_id` for account `l10n_bd_100502`. Solution: Remove `account_stock_expense_id` from the Bangladesh account template mapping. opw-5944874 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261311
This update corrects an issue where signatures were incorrectly duplicated on generated order PDFs after a signed order was modified. Moving forward, signatures will only be printed on documents created directly by the signature process, ensuring consistency and accuracy in order documentation. This enhances the reliability of our sales records.
Original PR description
A signed order can be modified afterward while retaining the signature on the newly generated PDF. After this commit, we will only print the signature on the document generated by the signature itself and not on any generated PDF afterwards. opw-6159170 Forward-Port-Of: odoo/odoo#261288
This update resolves an issue where the automated report generation process (cron) incorrectly fetched vendor invoices when running with a default company different from the intended target companies. The fix ensures invoices are retrieved from the correct company, preventing errors and improving the reliability of the reporting process.
Original PR description
In a multi-company context, the cron might be run with a user having a default company that is not the same as the target moves companies, maybe raising a `RedirectionWarning` (if the current company is not fully set-up). This commit ensure to fetch the invoice in move's target company. opw-5225553 Forward-Port-Of: odoo/enterprise#115350 Forward-Port-Of: odoo/enterprise#113254
This update corrects a display issue where portal users could see a 'View Timesheets' button on invoices, even if they lacked the necessary permissions. The fix ensures the button only appears for users who actually have access to the related timesheets, improving data security and user experience.
Original PR description
sale: add sale order specific hook to extend page values ------ Allows adding custom data (e.g., timesheets) without overriding generic _get_page_view_values sale_timesheet: hide 'View Timesheets'…
sale: add sale order specific hook to extend page values
------
Allows adding custom data (e.g., timesheets) without overriding generic _get_page_view_values
sale_timesheet: hide 'View Timesheets' button for users without access
-------
Steps to Reproduce:
-----------------
- Create a product with the invoice policy set to Based on Timesheets
- Enable Project and Tasks on the order.
- Create and confirm a sale order using a portal user.
- Log timesheets on the related task.
- Create an invoice from the sale order.
- Log in as the portal user and open the invoice.
- Click the 'View Timesheets' button.
Issue:
-------------
The 'View Timesheets' button is shown to the portal user even though they don’t have access to view timesheets.
Root Cause:
------------
The timesheets are linked to the sale order, so the button appears based on the timesheet_count, but the portal user does not actually have permission to access those timesheets.
Fix:
-----------
We replaced the timesheet_count check with a check that verifies whether the user actually has access to any of the related timesheets.
task-4745519
Forward-Port-Of: odoo/odoo#261681
Forward-Port-Of: odoo/odoo#209552This update resolves a bug where portal users were incorrectly seeing the 'View Timesheets' button, even without the necessary permissions. The fix involved updating a helper method to ensure users only see the button when they have the appropriate access rights, improving the user experience and preventing confusion.
Original PR description
**Issue:** The 'View Timesheets' button is shown to the portal user even though they don’t have access to view timesheets. Currently, we have added _sale_order_get_page_view_values in the sale module, which is overridden in sale_timesheet. We are using it here. task-4745519 Forward-Port-Of: odoo/enterprise#115193 Forward-Port-Of: odoo/enterprise#113481
This update fixes an issue where tax return rounding wasn't correctly applied when a company had multiple branches. The previous system aggregated rounding values, leading to inaccurate closing entries. The fix ensures that rounding is calculated and applied correctly for each company and branch, improving tax reporting accuracy.
Original PR description
Some countries lile Estonia, Nederlands or France apply a rounding from the tax report by adding a line to the end of the query results representing the sum of the roundings on each line of the tax…
Some countries lile Estonia, Nederlands or France apply a rounding from the tax report by adding a line to the end of the query results representing the sum of the roundings on each line of the tax report. When having a company with branches, the rounding is applying in each closing move (one per company/branch) but the value is coming from the aggregated report lines, this leads to wrong computation of the closing entries. Cause: In `_generate_tax_closing_entries` we loop over each company, therefore `_compute_tax_closing_entry` is called one time for each company, but it uses the report options containing all companies Fix: Use options with only the current company in `_compute_tax_closing_entry` Steps: - Install FR localisation - Select FR company and create two branches - Create, for last month: - 1 bill for parent company (100 with tax 20% G) - 1 invoice per branch (200 and 300 with tax 20% G) - Create a tax return with opining date at the beginning of the current month - Submit the last return and go to the created closing entries -> See that closing entries are wrong opw-5976359 Forward-Port-Of: odoo/enterprise#115116 Forward-Port-Of: odoo/enterprise#110652
This update resolves an issue where generating timesheets after archiving an employee would trigger an error. The fix prevents timesheets from considering time-off requests for previously archived staff, ensuring accurate timesheet generation. This improves data integrity and prevents disruptions to payroll processes.
Original PR description
[FIX] project_timesheet_holidays: Exclude archived employees from time-off # Description of the issue/feature this PR addresses: ## Steps to Reproduce: 1. Create a time off for Employee A (it should…
[FIX] project_timesheet_holidays: Exclude archived employees from time-off # Description of the issue/feature this PR addresses: ## Steps to Reproduce: 1. Create a time off for Employee A (it should affect the timesheets). 2. Create a new public holiday (global time off) that overlaps with Employee A’s time off. 3. Archive Employee A. 4. Delete the public holiday created in step 2. 5. An error related to timesheet generation appears. ## Expected Behavior: - The public holiday / global time off should be deleted without any error. # Desired behavior after PR is merged: ## Fix (Implemented): When regenerating timesheets due to changes in holidays or time off, leaves related to archived employees should not be taken into account. A check was added inside the `_generate_timesheets` function in `project_timesheet_holidays/models/hr_holidays.py` to exclude leaves belonging to archived employees. ## Alternative Fix (Not Implemented): Instead of filtering out leaves linked to archived employees, we could delete those leaves when an employee is archived. However, this approach is not ideal, as archived employees may be reactivated later and would still need their previously requested time off to be preserved. ## Version: This bug appears in both version 17.0 and 19.0. I assumed that it also appears in 18.0 but didn't directly test ## Task: [5474038](https://www.odoo.com/odoo/project/4105/tasks/5474038) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261412 Forward-Port-Of: odoo/odoo#244203
This update resolves an issue where the 'Remove Format' function would get stuck in an infinite loop when applied to text with icons and background colors in the To-do app. The fix ensures that icons are correctly identified and processed during format removal, preventing the loop and restoring normal functionality.
Original PR description
Steps to reproduce: =================== 1. Open the To-do app and pick any task. 2. In the description add text and an icon with a bg color. `(you can add this: <i class="fa rounded rounded-circle…
Steps to reproduce: =================== 1. Open the To-do app and pick any task. 2. In the description add text and an icon with a bg color. `(you can add this: <i class="fa rounded rounded-circle fa-user bg-o-color-1 fa-4x" contenteditable="false"></i>)` 3. Select all and click "Remove format". Result: -> Traceback due to an infinite loop. Cause: ====== Remove format calls `removeAllColor()`, which loops forever at: https://github.com/odoo/odoo/blob/626bde21a25366d0bb29662bae2057c247a1638e/addons/html_editor/static/src/main/font/color_plugin.js#L194-L194 Why: _applyColor doesn't remove the icon's background class, so hasAnySelectedNodeColor keeps returning true and the removal loop never terminates. This happens because `font` is already the `<i>` element with the `fa` class, using `querySelectorAll` on it won't include the element itself, so the icon is never checked or updated. https://github.com/odoo/odoo/blob/6cdc6f55886ea48e90f9023a6c6142bf072745b9/addons/html_editor/static/src/main/font/color_plugin.js#L290 Solution: ========= Check if the font itself has the fa class before doing the `querySelectorAll`, and include it in the nodes to check for color. Test Impact: ============ Before this fix, a `<span>` containing an icon was wrapped in a `<font>` when applying color, treating the icon as a normal span (without size) instead of applying the color directly. https://github.com/odoo/odoo/blob/8792c2d38eb0aadac8d778d83fd76f270404ecd5/addons/html_editor/static/src/main/font/color_plugin.js#L397 opw-5928627 Forward-Port-Of: odoo/odoo#261405 Forward-Port-Of: odoo/odoo#248449
This update resolves a technical issue preventing blackbox orders on self-order kiosks from generating correct receipts. The change re-introduced a necessary field, '_server_version', to the configuration, ensuring the kiosk can properly validate and create receipts. This ensures consistent receipt generation for a critical point of sale function.
Original PR description
In odoo/odoo#258744, the `pos_self_order` module was optimised to only send the fields required for the kiosk to function. This also meant the `_server_version` field was no longer sent in the `pos.config`. Because of this, there is now a traceback when validating a blackbox order in the self order kiosk, as it relies on the `_server_version` field to make the receipt. This commit fixes the issue by adding the `_server_version` to the `pos.config` as an override in the `pos_blackbox_be` module.
This update resolves an issue where reports for Withholding Taxes (WHT) were incorrectly mixed with VAT closing entries. Removing the specific return type for WHT ensures accurate reporting and prevents data confusion, leading to more reliable financial data. This improves the clarity and accuracy of financial reports.
Original PR description
WHT does not require a closing entry. The current return type is causing VAT closing entry to mix with WHT closing entry or vice versa. task-6157814
This update addresses a problem where payruns were incorrectly flagged as missing in the 19.1 release for the Belgian HR Payroll module. The fix removes a dependency on company-level closing dates, aligning the payrun logic with a previous request (GMF). This ensures accurate payrun generation and reporting.
Original PR description
In this commit, we removed the missing payrun issue from 19.1, since we are missing the closing_date in company-level and the missing payrun should depend on that value (GMF request). task-6008297
This update fixes an issue where byproducts added directly to manufacturing orders weren't correctly linked to stock movements. Now, byproducts added to MOs are properly tracked, ensuring accurate inventory and production reporting. This improves the reliability of shop floor data.
Original PR description
When we add a byproduct followed by SN directly in the MO it will not have the its location as production. Steps to reproduce: ------------------- * Create product tracked by Serial number * Create a…
When we add a byproduct followed by SN directly in the MO it will not have the its location as production. Steps to reproduce: ------------------- * Create product tracked by Serial number * Create a Manufacturing order * Add the Product tracked by serial number on the MO as byproduct * Confirm the MO * Go to shop floor * Add the by-product quantity and create a new serial number. * Close production and go back to the MO in manufacturing * Open stock moves -> the by-product does not have "production" for origin Observation: ------------- When we add the byproduct directly in the MO, they will be added to move_byproduct_ids in the MO but not in byproduct_ids on the stock.move because byproduct_ids it's a [link](https://github.com/odoo/odoo/blob/d14bf6289da21065860ff959185c47b947a7418c/addons/mrp/models/stock_move.py#L50-L52) between the stock.move and the BOM. When adding the byproduct in shopfloor, it will create the quant: https://github.com/odoo/enterprise/blob/06be616bb4d74f0a089e8e318d25c2424594f813/mrp_workorder/static/src/mrp_display/mrp_record_line/stock_move.js#L163-L171 Additionaly when creating the quant it will decide the source location depending if the product its a byproduct: https://github.com/odoo/enterprise/blob/1d10ee238a50e7bdb552efdeafc068c5127cd49a/mrp_workorder/static/src/mrp_display/mrp_record_line/stock_move.js#L189-L192 The issue arise because it check if the product it's a byproduct by checking byproduct_ids and since our product was added directly on the MO and not from the BOM it will not appear in byproduct_ids https://github.com/odoo/enterprise/blob/dc5bb0fe8e15063f977970841bdaf8aff1a61e41/mrp_workorder/static/src/mrp_display/mrp_record_line/stock_move.js#L108-L110 #### Additional notes: The default value for [byproduct_id](https://github.com/odoo/odoo/blob/abb5777cc8324cff0cdf841a8ae42413060dcf92/addons/mrp/models/mrp_production.py#L1263) when creating the stock move is false opw-5974582 Forward-Port-Of: odoo/enterprise#110122
This update resolves an issue where commission calculations were failing for recurring subscription orders due to an empty currency rate table. The fix adds a fallback rate, ensuring commissions are correctly applied when currency rates are not initially populated. This prevents lost revenue and ensures accurate commission payouts for subscription-based sales.
Original PR description
Steps to reproduce: 1- Installed sale_commission_subscription and accounting 2- Go to [Sales -> Commissions -> Commission Plans] 3- Create a new commission plan of type MRR, specify a salesperson and approve 4- Go to Subscriptions app and create a new order with a recurring monthly plan and specify the same salesperson 5- Create an invoice for the order and confirm it 6- Go back to the commission plan and click on the Commissions smart button Issue: Commissions show up as 0 Expected behavior: Should have the corresponding commission based on the rate specified Why this happens: The `res_currency_rate` table is empty by default and only gets populated if you are in a multi-currency environment and sync the rates in the settings or by manually making a currency rate entry. Since the commission calculation depends on this table, it results in 0 rows when joining the sub-query. opw-6108580 Forward-Port-Of: odoo/enterprise#114354
This update fixes an issue where the ewallet discount was incorrectly included in delivery calculations. The change adjusts the pricing logic to accurately exclude ewallet amounts from delivery costs, ensuring consistent and accurate shipping charges for customers. This improves the customer experience and prevents overcharging.
Original PR description
Issue: --- Ewallet line is included in delivery pricing. Steps to reproduce: 1- Create a delivery method `based on rules`. 2- In pricing set rules: - price <= 99 => delivery price = 30 - price > 99…
Issue: --- Ewallet line is included in delivery pricing. Steps to reproduce: 1- Create a delivery method `based on rules`. 2- In pricing set rules: - price <= 99 => delivery price = 30 - price > 99 => delivery price = 50 3- Create a eWallet with balance = 200. 4- Create a SO add a line with product. Set the SOL unit amount to 100. 5- Click on `add a shipping`. Add the created delivery method. 6- As you see, the delivery amount is correctly calculated. 7- Now apply the eWallet using `reward` button. 8. Update the shipping cost. The shipping cost is 30, which is not expected. Cause: --- In calculation of shipping amount the ewallet is not taken into account. Even though technically it's considered a discount, ewallet is not functionally the same as discount. However, in `_get_price_available` we cannot have information about `ewallet` lines as it doesn't depend on `sale_loyalty`. Fix: --- We use `_compute_amount_total_without_delivery` which is overridden in `sale_loyalty_delivery` to exclude ewallet and gift cards. opw-6124209 Forward-Port-Of: odoo/odoo#260134
This update allows accountants to retain KSEF XML files associated with invoices. Previously, these files were automatically discarded after being used to fetch data. Now, the XML files are attached to the corresponding invoice, providing a permanent record for accounting and compliance needs.
Original PR description
Description of the issue this commit addresses: When fetching the bills from ksef, the xml with the data about the move is received, parsed and then discarded but the XML can be required to be kept for longer than ksef keeps it so we are lacking a way for an accountant to download it and store it locally. --- Desired behavior after this commit is merged: When a move is fetched from ksef via an xml file, that file is put as an attachment on the move created with its data. --- task-6076505 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259655