Tuesday, April 14, 2026
13 changes · saas-18.4
Resolved issues and error corrections
Fixes the Time Off balance report so allocated and used leave days are matched to the correct allocation period. This prevents incorrect remaining balances and avoids rows appearing in the wrong year for users in non-UTC time zones.
Original PR description
__ISSUE__: - FIFO balance miscalculation for non-overlapping allocations. cumulative_allocated_days was partitioned globally by (employee, leave_type), but taken_per_allocation scoped leaves to each…
__ISSUE__:
- FIFO balance miscalculation for non-overlapping allocations. cumulative_allocated_days was partitioned globally by (employee, leave_type), but taken_per_allocation scoped leaves to each allocation's date range. This caused the FIFO formula to silently absorb leaves from one period into another's allocation capacity.
ex:
Alloc A (20 days) 2025, taken leaves 15 days
Alloc B (20 days) 2026, taken leaves 5 days
report: 2025: (15 taken), (5 left)
2026: (7 taken), (20 left)
- Left" rows shifted by one year in non-UTC timezones. Allocation date_from/date_to (Date fields) were cast to timestamp as midnight UTC. In negative-UTC /positive-UTC timezones midnight UTC of Dec 31 renders as the prev/next day.
__FIX__:
- detect overlap groups using a running MAX(date_to) and partition the cumulative sums within each overlap group. This way non-overlapping allocations are treated as independent, while overlapping or open-ended allocations still share FIFO within their group.
- offset allocation dates by 12 hours so no timezone can shift them across a day boundary.
- opw-5169606
- opw-5352114
Forward-Port-Of: odoo/odoo#257873Fixed an issue where sales orders in a multi-company setup could use the wrong project's analytic account. This ensures costs and revenues are assigned to the correct company project when confirming service sales.
Original PR description
Pre-requisites: ------------------------------------------ 1. Install `sale_project` and `project_account_budget` modules 2. Have two companies configured in the system 3. Enable Timesheets from the…
Pre-requisites:
------------------------------------------
1. Install `sale_project` and `project_account_budget` modules
2. Have two companies configured in the system
3. Enable Timesheets from the Settings app
4. Create two projects (one for each company)
5. Ensure the following settings are enabled on both projects:
* Timesheets
* Billable
Steps to Reproduce:
------------------------------------------
1. Switched to Company A
2. Create a product with:
* Type: Service
* Create on Order: Task
* No company restriction
3. Set the product's `project_id` to Company A's project
4. Switch to the newly created company (Company B)
5. Set the product's `project_id` to Company B's project
6. Enable Analytic Distribution from SOL Optional
7. Create a sale order with the configured product, and delete the auto-fetched
Analytic Distribution account for the sale order (Company B's project)
8. Now confirm the sale order
Observation:
----------------------------------------
The SOL's analytic distribution uses the analytic account from Company A's project instead of Company B
Issue:
----------------------------------------
The `project_id` field on `product.template` is `company_dependent=True`, meaning it stores different values per company. However, in `_compute_analytic_distribution()`, the code accesses `line.product_id.project_id` without calling `with_company`, so it resolves the field using the wrong company context
Solution:
----------------------------------------
using `with_company()`, the correct company context is applied when accessing
`project_id`, preventing inconsistencies in multi-company environments and
ensuring the appropriate project is used for the corresponding company.
opw-5864452
Forward-Port-Of: odoo/odoo#257776Customers buying event tickets through Point of Sale with an online payment method will now see the ticket download button on the confirmation screen. This fixes a gap where online-paid orders were still marked as draft when ticket information was prepared, preventing customers from immediately accessing their tickets.
Original PR description
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and…
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and pay with the online payment method - Once on the ticket screen, the button to download the event tickets is not displayed **Why the fix:** The normal flow only works for offline payment methods, because we check if the ordered is either paid or invoiced before setting all the values needed by the frontend regarding the ticket registration. The problem is that with an online payment method, once we enter the **read_pos_data** method that sets the values for the frontend, the order is still in draft, so we just return without doing anything. We now set the values regardless of the order's status and send the confirmation mail in the same way as if it was an online payment. In the case of an online payment, the mail will be sent by the **action_pos_order_paid** function that is called once the payment is processed. A test might be a bit weird to make as we don't have a bridge for pos_online_payment and pos_event, and that we would need to mock the server's answer to be able to pay for the online payment and check that we have the needed values. So the setup for pos_event would have to be copied into pos_online_payment to test it and it would only be ran if both modules are installed. opw-5438432 Forward-Port-Of: odoo/odoo#257593 Forward-Port-Of: odoo/odoo#249306
Sales orders for products invoiced on delivered quantities now show the correct invoice status after all delivered items are returned. This prevents fully returned orders with nothing invoiced from being incorrectly marked as fully invoiced, reducing confusion for sales and accounting teams.
Original PR description
### Issue before this commit: When a sales order with a product invoiced on delivered quantities is fully delivered and then completely returned the delivered quantity is reset to zero. In this…
### Issue before this commit: When a sales order with a product invoiced on delivered quantities is fully delivered and then completely returned the delivered quantity is reset to zero. In this situation, where nothing has been invoiced and nothing remains to be invoiced, the invoice status of the sales order line is incorrectly set to "Fully Invoiced" instead of "Nothing to Invoice". ### Steps to reproduce the issue: 1. Create a new quotation for a storable product. 2. Confirm the order. 3. Validate the delivery of the product. 4. Perform a return for the product 5. Validate that return to simulate a customer return. 6. The sales order details correctly reflect that the delivered quantity and invoiced quantity are both zero. Despite these values—which indicate there is nothing to invoice—the invoice status on the quotation erroneously displays as "fully invoiced". ### Cause of the issue: The invoice status computation includes a fallback logic that marks a sales order line as "invoiced" when all related stock moves are either done or cancelled. However, this logic does not verify whether any quantity remains effectively delivered. As a result, after a full return, even when qty_delivered = 0, the condition is still met and the line is incorrectly marked as fully invoiced. ### Reason to introduce the fix: A fully returned sales order line with no delivered and no invoiced quantity should not be considered fully invoiced. The fix ensures that the fallback to "invoiced" only applies when there is a strictly positive delivered quantity, preventing incorrect invoice status after full customer returns. opw-6014772 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257942 Forward-Port-Of: odoo/odoo#254871
Delivery slips now use the currency selected on the sales order when showing product values. This prevents incorrect amounts on commercial invoices for multi-currency sales and helps businesses avoid customer confusion or documentation errors.
Original PR description
The product value reported on delivery slips may incorrectly use the company currency instead of the order currency. Steps to reproduce: - Enable multi-currency and create a foreign currency - Create a pricelist in the foreign currency - Create and confirm a Sale Order using that pricelist - Add a delivery via carrier (eg. Fedex) - Confirm the delivery and generate the commercial invoice. Issue: The 'sale_price' on the stock move lines is taken in company currency rather than order currency. opw-6104130 Forward-Port-Of: odoo/odoo#258875
This update fixes issues when editing quoted content in Odoo's HTML editor. Users can now delete images or tables inside quotes without breaking the quote, avoid extra blank lines after tables, and create lists directly inside quotes.
Original PR description
Description of the issue this PR addresses: - Pressing Backspace inside a blockquote that has visible content but no text content removes the blockquote instead of the content. The content (image or table) gets moved outside of the blockquote. - Trailing BR was kept after tables because tables are marked as unsplittable blocks. This left unnecessary BR nodes after tables in blockquote. - Lists could not be created inside a `blockquote`. Desired behavior after PR is merged: - Backspace removes the inner content first when blockquote contains nodes. - Trailing BR is removed when placed table inside blockquote. Cursor can still be placed at the edge of the table without requiring a BR anchor. - Lists can be created directly inside a blockquote. task-5864080 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258552 Forward-Port-Of: odoo/odoo#245011
The Time Off balance report now groups employees by their current department instead of the department stored when an allocation was created. This prevents duplicate employee entries after department changes and gives managers a cleaner, more accurate view of leave balances.
Original PR description
Steps to reproduce: ------------------------- 1. Install the Time Off module. 2. Go to Time Off > Management > Allocations, create an allocation for an employee, and approve it. 3. Go to Reporting >…
Steps to reproduce: ------------------------- 1. Install the Time Off module. 2. Go to Time Off > Management > Allocations, create an allocation for an employee, and approve it. 3. Go to Reporting > Balance and apply the filter Department > Employee. 4. Change the employee’s department. 5. Create an allocation for the same employee and approve. 6. Apply the Department > Employee filter again. Observed behaviour: ---------------------------- After a department change: * Existing allocations keep the old department * New allocations use the new department As a result, duplicate employee entries appear in the report Cause: ---------- It is using allocation.department_id. Allocations store the department at creation time, which may differ from the employee’s current department, causing an incorrect report filtering. Solution: ------------ Fetch department_id from hr_version instead of hr_leave_allocation in the hr_leave_employee_type_report. This ensures: * Leave balances always follow the employee’s current department * Correct aggregation when grouping by Department → Employee opw-5220577 Before: <img width="1238" height="857" alt="image" src="https://github.com/user-attachments/assets/15e1293b-dc50-4067-a12f-079c046c2074" /> After: <img width="1247" height="824" alt="image" src="https://github.com/user-attachments/assets/feea32de-0d9c-4eef-9ae5-639f4658560c" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users can now edit website profile pages from mobile devices without encountering an error. The fix restores the same editing experience used on desktop, helping learners and administrators manage profiles reliably on smaller screens.
Original PR description
# How to reproduce - Install the eLearning module - On the website, go to the Courses tab - View a user (Administrator for example) - In mobile view, click on Edit # The problem An traceback is shown and the user cannot edit their profile # Why This commit (https://github.com/odoo/odoo/commit/69785c1a64d61f2831804bcdcc4887ad43d27fbb) improved the profile edition. It is mentioned that they moved away from the simple bootstrap modal and used an OWL view instead. However, for the mobile view, they left a call to a modal that does not exist. This fix removes the call to the undefined modal and replaces it with the same OWL Dialog used in the desktop view (thanks to the .o_wprofile_editor class) opw-5960586 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Spanish shared-ownership entities with VAT numbers starting with E are now treated like individual freelancers for tax and accounting purposes. This prevents incorrect fiscal categorization in Spanish EDI reports and tax workflows.
Original PR description
In Spain, "Comunidades de Bienes" (VAT starting with 'E') are entities without legal personality that tax via income attribution to their members. For accounting and tax reporting purposes, they must be treated as individuals/freelancers rather than corporations. The current _l10n_es_freelancer logic was too restrictive, only matching standard DNI (8 digits + letter) or NIE (starting with X, Y, Z). This caused CBs to be excluded from freelancer-specific logic, leading to incorrect fiscal categorization in reports and tax modules. The regex has been updated to optionally allow the 'E' prefix while ensuring the rest of the string maintains a valid format, effectively broadening the scope of what the system considers a Spanish freelancer. task-6014192 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258474 Forward-Port-Of: odoo/odoo#253087
Customers buying event tickets or similar service-based products can again complete checkout without re-entering full billing address details by default. This reduces friction after registration details have already been collected, while still allowing businesses to require full billing addresses through a setting when needed.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258347
This update resolves an error preventing customers from successfully connecting or refreshing their Shopee accounts through the Odoo module. The fix corrects a technical issue within the module's code that was causing an error during the authorization process. New automated tests have been added to ensure this functionality remains stable.
Original PR description
Currently, customers report errors when connecting or refreshing a Shopee account through the `sale_shopee` module. **Steps to reproduce:** - Install and configure the `sale_shopee` module - Attempt…
Currently, customers report errors when connecting or refreshing a Shopee account through the `sale_shopee` module. **Steps to reproduce:** - Install and configure the `sale_shopee` module - Attempt to connect a Shopee account via the onboarding flow - Complete the authorization process **Observed behavior:** An error is raised during the authorization callback, preventing the Shopee account from being connected or refreshed. **Root cause:** In `onboarding.py`, the `shopee_return_from_authorization` controller incorrectly uses `utils.with_context(authorization_code=code)`. Since `utils` is an imported Python module, calling `with_context` on it attempts to set the context on the module itself rather than on a model instance, which raises an error. **Solution:** Move the `with_context` call from the `utils` module to the `temp_shop` record, which is the appropriate model instance that needs the context. Additionally, this commit adds regression tests for the controller to prevent future regressions, as this functionality was previously untested. opw-6092524 Forward-Port-Of: odoo/enterprise#113081
This update corrects a bug where ticket submissions with emails using different capitalization would incorrectly create a new partner record. Now, the system correctly identifies and uses the submitted email address to create a ticket without generating a new partner, ensuring accurate ticket assignment and data management.
Original PR description
**Steps to reproduce** - Create a first partner (name: "Partner", email: "partner@mail.com", phone: "123"). - Go to the website form of a helpdesk team, and submit a ticket using "Partner@mail.com"…
**Steps to reproduce**
- Create a first partner (name: "Partner", email: "partner@mail.com", phone: "123").
- Go to the website form of a helpdesk team, and submit a ticket using "Partner@mail.com" as email (notice the different capitalization) and "456" as phone number.
Behavior without this fix: a new partner is created, but the ticket is assigned to the orignal partner ("partner@mail.com") and its phone number is updated.
Behavior after this fix: no partner is created.
**Causes**
- the partner search was case sensitive
- the created partner was not used as the `partner_id` of the ticket as it was added to the params but needs to be in the kwargs passed to `handle_website_form` in order to be found used by `extract_data`. The original partner was found in `_find_or_create_partner` by the call to
`_mail_find_partner_from_emails` (case-insensitive)
Note: this commit also ensures consistency between the partner's company and the ticket's company (same as in `_find_or_create_partner` of `helpdesk.ticket`).
Also, avoid allowing modifying existing partner's phone via this form.
opw-5914064
Forward-Port-Of: odoo/enterprise#109393This update fixes a previous issue where quick checkout was disabled for event and appointment sales. We've refined the process to automatically enable quick checkout for these events, recognizing that billing addresses are typically tied to the event location rather than the customer. A system parameter allows businesses to retain full billing address details if needed.
Original PR description
Forward-Port-Of: odoo/enterprise#113575