Monday, October 27, 2025
21 changes · 19.0
New functionality added to Odoo
Users can now upload e-Receipt XML files exported from the Nilvera Portal directly from the Receipts list. Odoo creates draft receipts from the uploaded files and opens the resulting records, reducing manual entry for Turkish e-dispatch workflows.
Original PR description
This PR introduces a new option to import e-Receipt XML files exported from the Nilvera Portal. - An "Upload e-Receipt (XML)" button is now added in the list view of Receipts (stock picking). - Upon upload, draft receipts are created based on the XML data. - After successful import, the user is redirected to a new view displaying the generated receipts. TaskID:4452521 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231908 Forward-Port-Of: odoo/odoo#217530
Enhancements to existing features
When importing a data module fails, users now see the full error details instead of only the final part of the message. This makes it easier to understand what went wrong or share complete information with support for faster troubleshooting.
Original PR description
Before this commit, when an error happens during the import of a data module, the UserError was displaying the last part of the traceback. In some cases, it was sufficient (missing manifest, unknown dependency, ...). But in other cases, this was only displaying the record triggering the error, but not more, giving no clue on what was the exact error and how to fix it. This commit adapts the UserError to provide the full traceback in the popup window, such that the user can understand or at least report the error. Another task is targeting master to improve the design of this window. task-4876416
Resolved issues and error corrections
German POS sessions can now be closed even when an order includes products without taxes. The system treats untaxed lines as 0% tax when sending required data to Fiskaly, preventing checkout session closure failures.
Original PR description
Steps to reproduce: ------------------------- - Install the German localization with the POS module. - Register the company to fiskaly. - Create an order that includes a product with no taxes. - Attempt to close the POS session. Issue: ------- - There will be a traceback and session cannot be closed. Cause: --------- - While sending data to Fiskaly, the code references `l.tax_ids[0].amount`so If a line has no tax, this results in an error because there is no handling for an empty tax list. Fix: ----- - If a line has no tax, treat it as a 0% tax and fetch the corresponding `vat_definition_export_id` accordingly. opw- 5145258 Forward-Port-Of: odoo/enterprise#97076
Fixes an error that could occur when users opened an employee's Monthly Hours after enabling Display Extra Hours. This keeps attendance and time-off information accessible without requiring technical support or workarounds.
Original PR description
Currently, an error occurs when opening the "Monthly Hours" smart button on an employee record after enabling the "Display Extra Hours" feature. **Steps to Reproduce:** 1. Install "Attendances" and…
Currently, an error occurs when opening the "Monthly Hours" smart button on an employee record after enabling the "Display Extra Hours" feature.
**Steps to Reproduce:**
1. Install "Attendances" and "Time off" modules with demo data.
2. In Settings, enable the "Display Extra Hours".
3. Open any employee and click on "Monthly Hours" smart button.
**Error:**
`TypeError - Domain.AND() takes 1 positional argument but 2 were given`
**Cause:**
At [1], the domain was incorrectly passed as two separate arguments to `Domain.AND()`, which must be wrapped inside a list. Fixing by-passing a single argument leads to another issue because the ORM call at [2] passes a domain for the `hr.attendance` model, which includes fields like `check_in` and `check_out`. These fields do not exist on the `hr.leave.allocation` model, leading to the `ValueError: Invalid field hr.leave.allocation.check_in in condition ('check_in', '>=', '2025-09-30 18:30:00')`.
**Fix:**
This commit fixes the issue by skipping invalid domain filters that do not exist on the `hr.leave.allocation` model before calling `_read_group` method.
[1] - https://github.com/odoo/odoo/blob/041c70150ee50ef58c02dbcec157adb646cfcde5/addons/hr_holidays_attendance/models/hr_employee.py#L17-L22
[2] - https://github.com/odoo/odoo/blob/041c70150ee50ef58c02dbcec157adb646cfcde5/addons/hr_attendance/static/src/views/extra_hours_list_view.js#L37
sentry-6917312916Helpdesk can now create tickets from incoming emails even when the sender's email matches a contact assigned to another company. This prevents missed customer requests in multi-company setups by ensuring the ticket uses a company-appropriate contact instead of failing.
Original PR description
**Steps to reproduce** - Have a helpdesk team for company A, with an email alias set up. - Have a `res.partner` belonging to company B with an email. To reproduce, there should be no contact with…
**Steps to reproduce** - Have a helpdesk team for company A, with an email alias set up. - Have a `res.partner` belonging to company B with an email. To reproduce, there should be no contact with this email in company A or with no company. - Send a message with the email of the `res.partner` to the alias of the helpdesk team. Issue: the ticket is not created. **Cause** The `_check_partner_id_has_the_same_company` constraint fails, preventing the ticket from being created. **Solution** We stop using the `author_id`, since it is not guaranteed to respect the constraint. https://github.com/odoo/enterprise/blob/a1fe558c8d6e27b435d350c23e19b93bbe611eb7/helpdesk/models/helpdesk_ticket.py#L755 This values comes from `_mail_find_partner_from_emails` in the mail module, which will prioritise a contact from the same company, but will not prevent one from another company being used. The existing code in `create` will call `_find_or_create_partner` to find/create one based on the name and mail. `_mail_find_partner_from_emails` is used instead of `find_or_create` to be able to provide an additional domain to ensure company consistency. opw-5154449 Forward-Port-Of: odoo/enterprise#98129 Forward-Port-Of: odoo/enterprise#97734
Italian electronic bill imports now avoid applying the same discount twice when the XML includes both a discount element and a matching negative line. This helps ensure imported supplier bills show the correct amount due and reduces manual correction work for accounting teams.
Original PR description
When importing a bill in an IT company the system will automatically parse the xml and populate the record. In case of discount, an element <ScontoMaggiorazione> will be present, either for the whole document or for a single line. However, an extra negative line may be present in the xml representation of the bill, creating a double discount **Steps to reproduce** - With an IT Company setup - Import an xml bill having <ScontoMaggiorazione> element and a negative line representing the same discount **Issue** Double discount line will be created in the bill **Analysis** This occurs because, when parsing the bill, the system will import also negative lines, even if a discount has been already applied opw-4913335 [Ticket link](https://www.odoo.com/odoo/project/49/tasks/4913335) Forward-Port-Of: odoo/odoo#232880 Forward-Port-Of: odoo/odoo#225044
Creating a new talent directly inside a talent pool now correctly links any application created from that talent back to the same pool record. This prevents duplicate talent records and ensures recruiters see the expected Talent Pools button instead of being prompted to add the application to a pool again.
Original PR description
**Steps to reproduce** - Recruitment > Applications > By Talent Pools - Click on a talent pool - Click on "New" and create a new talent - Click on "Create applications" and create one Issue: "Add to Pool" button appears, when we would except the "Talent Pools" smart button to appear, linking the new application to the previously created talent. This leads to the creation of duplicates talents. **Cause** `pool_applicant_id` is not set on either the talent, or the created applicant. In the original flow, when adding an applicant to a pool, `_add_applicants_to_pool` ensures `pool_applicant_id` is set to the talent for both the talent and the new applicant. **Fix** Since it's now possible to directly create talents in a pool, we set `pool_applicant_id` at creation. opw-5117977
Work entries generated from company-wide time off now use the relevant employee, contract, or company time zone instead of defaulting to UTC. This prevents leave-related work entries from appearing on the wrong day for organizations operating outside UTC.
Original PR description
**Steps to reproduce** 1. Have a company and employee using a calendar in UTC+8, with attendances in the calendar starting at 7am. 2. Create a global time off generating a work entry. 3. Generate work entries for the employee. Issue: the work entry generated by the global time off is 1 day earlier than expected. **Cause** The date used was in UTC, ignoring the tz defined on the version/ employee/company. https://github.com/odoo/odoo/blob/192c2d98f7bf871c4f221aaa36c1cb2a541d3945/addons/hr_work_entry/models/hr_version.py#L503-L510 opw-5106975
This fixes an issue in self-ordering where returning from the payment page could leave the cart in an incorrect state. Customers can now edit their cart normally and see the correct cart total after going back, reducing checkout confusion.
Original PR description
Steps to reproduce: =================== - Start a self-order session. - Add some products to the cart. - Navigate to the payment page. - Click the back button. Issue: ====== - When going back to the cart page from the payment page, products in the cart are not editable. - On the product page, the cart total shows 0. Cause: ====== - `lineChanges` were not cleared on back navigation, leaving previous data in the cart. Fix: ==== - Clear `lineChanges` when navigating back from the payment page to ensure a clean state. Task: 5055279 Forward-Port-Of: odoo/odoo#228672
This fix ensures automated rules and filters can find matching text even when it appears after a line break in a field such as a task description. This helps business automations trigger reliably when users format content with banners, paragraphs, or other multi-line text.
Original PR description
Problem: When the ilike comparator is applied in filtered_domain, it is unable to match text beyond a newline character (\n). This is due to the regex being used not having the DOTALL flag. Purpose: Add the DOTALL flag to the re.compile arguments when defining like_regex. Steps to Reproduce on Runbot: 1. Create an Automation Rule on the Task model with an Apply On condition of Description contains "test". 2. Create a Task and add an Info Banner element, then either within the element or afterwards include the "test" text, then save. 3. The automation rule does not trigger. opw-5134374 Forward-Port-Of: odoo/odoo#233124 Forward-Port-Of: odoo/odoo#232434
FedEx rate requests no longer fail when a customer's state code is longer than FedEx accepts, such as East Flanders in Belgium. Odoo now leaves out that optional state field when needed, helping sales users get shipping rates reliably for affected international customers.
Original PR description
**Issue**: Sending a `stateOrProvinceCode` longer than 2 characters causes a FedEx error. **Steps to reproduce**: - Ensure the FedEx delivery carrier is installed. - Open the Sales application. - Create a new quotation with a Belgian customer whose state is set to `East Flanders`. - Click on "Add shipping". - Select "FedEx International" and click on "Get rate". - An error is raised. **Cause**: Some Odoo state codes are longer than 2 characters and are not covered by [this commit](https://github.com/odoo/enterprise/commit/38276c9a237a1779ce7a3e6f31102ff615691690). **Solution**: According to FedEx developer support, in such cases the `stateOrProvinceCode` field is not required. Therefore, we simply omit sending it when the code length is invalid. **Additional note** This commit also fixes 3 mistakes among the mandatory countries: - 3 for United Arab Emirates opw-4875939 Forward-Port-Of: odoo/enterprise#93642
Fixed an issue where changing rental dates in the online cart could shift the layout and make quantity buttons stop working. Customers can now adjust rental periods without disrupting the cart experience or losing access to key actions.
Original PR description
Steps to reproduce: =================== 1. Add a meeting product to the cart with the "Rental" option checked. 2. Go to the cart and change the date range. → The cart layout shifts to the left, and…
Steps to reproduce: =================== 1. Add a meeting product to the cart with the "Rental" option checked. 2. Go to the cart and change the date range. → The cart layout shifts to the left, and quantity buttons become unclickable. Cause: ====== Two separate issues caused this behavior: 1. **Layout shift:** When updating the date range, `cart_quantity` can be undefined. The logic that determines whether to toggle the `col-lg-7` class relies on this value. When undefined, it incorrectly assumes the cart is empty and shifts the layout to the left. 2. **Unclickable buttons:** The following line replaces the entire `.js_cart_lines` element: https://github.com/odoo/odoo/blob/abf9bc083c5a219a0b6fc0346dcd2a2cb503e081/addons/website_sale/static/src/js/website_sale_utils.js#L88 This removes all old elements (and their event listeners) and inserts new ones from the server. As a result, interactive buttons (e.g., quantity update) lose their functionality. Older versions didn't face this issue because they used jQuery event delegation, which automatically handled dynamic elements. Solution: ========= 1. provide the cart_quantity value via the controller, 2. Restart the cart interaction after re-rendering to restore event bindings for clickable buttons. opw-5167866
Managers can now create employee appraisals as expected. This fixes an access-related issue in the Appraisals app and adds test coverage to help prevent the problem from returning.
Original PR description
fixed with https://github.com/odoo/enterprise/commit/d4b708d22c0c3768cbb50bd5a43e91db419ff277 added test to cover the use case opw-4794641 Forward-Port-Of: odoo/enterprise#87831
Fixed an issue that caused the stock valuation screen to crash when Arabic was enabled. This ensures users working in Arabic can access inventory valuation information without interruption.
Original PR description
Steps to reproduce the bug:
- activate Arabic language
- Try to open stock valuation
Traceback is triggered:
raise ValueError("time data %r does not match format %r" % ValueError: time data '٢٠٢٥-١٠-٢٢' does not match format '%Y-%m-%d'
opw-5176859This fixes an issue where changing the heading style of website titles, such as shop or cart headers, could make the text disappear. Website editors can now adjust header styles without risking accidental content loss.
Original PR description
Problem: When trying to change the header type of "All products" in the "/shop" page on Website, the title disappears. Cause: The title is `h1[data-oe-field]`. When we update it, we replace the node with a new header node. This triggers `handleMutations` with both the removed node and the new node. The old removed node with no content is processed in `normalizeHandler`, which causes removal of the content from the new node as well. Solution: In `FieldChangeReplicationPlugin.handleMutations`, filter out removed nodes so they are not processed in `normalizeHandler`. Steps to reproduce: 1. Enter Website. 2. Go to the cart and select the header "Order Summary". 3. Attempt to change the font style (Header 1, Header 2, etc.). → The header disappears. opw-5106712 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229486
Self-ordering now handles shared table QR codes differently depending on the payment flow. Customers paying separately no longer see or change each other’s orders, while pay-after-meal tables can still build one shared order together.
Original PR description
Before this commit orders were always shared between multiple devices using the same QR code. This could lead to issues when multiple customers were using self-ordering at the same table, as they could see and modify each other's orders. When multiple devices are used for self-ordering with the same QR code, there is now two mode possible: - Pay after each: orders are not shared, and the table isn't linked to the order when synchronizing. Instead the table number is in the floating order name. - Pay after meal: orders are shared, and the table is linked to the order when synchronizing. That's means that multiple devices can add products to the same order. taskId: 5187089 Forward-Port-Of: odoo/odoo#232659
Incoming emails sent to a project alias with duplicate address formats, such as a plain address plus a display name, no longer cause task creation to fail. This prevents affected emails from bouncing and helps teams reliably create project tasks from customer messages.
Original PR description
Description of the issue/feature this PR addresses: Task creation from incoming emails fails when the “To” header contains RFC-compliant email formats with display names, for example:…
Description of the issue/feature this PR addresses: Task creation from incoming emails fails when the “To” header contains RFC-compliant email formats with display names, for example: `support@company.com, "Support Team" <support@company.com>` Odoo interprets this as two separate email addresses. When processing, the system attempts to remove the project alias (`support@company.com`) from `unmatched_partner_emails` multiple times, which causes the error: `ValueError: list.remove(x): x not in list` Current behavior before PR: - Incoming emails with display names in the “To” field cause a `ValueError` in `project_task.py`. - Task creation via project alias fails and the email bounces. Desired behavior after PR is merged: - The system checks whether the alias email exists in the list before attempting to remove it. - No crash occurs, and task creation works correctly for emails with display names. Fix implemented: - Added a conditional check in `addons/project/models/project_task.py` before removing the alias address. - This ensures safe removal and prevents the `ValueError`. Fixes: #233133 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Invoice section and subsection behavior has been cleaned up so PDF invoices are easier to read and totals are calculated correctly. Users can no longer select conflicting display options that produced unreadable invoices, and section indentation is improved across layouts.
Original PR description
Few fixes for section and subsection feature. 1. Simplify the colspan calculation by removing the get_column_to_exclude_for_colspan_calculation Python method and performing all calculations in XML.…
Few fixes for section and subsection feature.
1. Simplify the colspan calculation by removing the get_column_to_exclude_for_colspan_calculation
Python method and performing all calculations in XML. This change makes it simpler to override
the behavior.
2. Add padding to make the PDF indentation more readable. The px-3 class was not enough on some
layouts, such as 'bubble' and 'boxed'.
3. Remove the possibility of having a section appear under both the "Hide Prices" and "Composition"
options. It doesn't make sense to enable both simultaneously, as the user should choose to either
hide the prices or the composition. A PDF with both options enabled is unreadable.
4. Technical refactor of the `_get_child_lines` method. This method is a bit messy and hard
to read. This commit adds a bit of clarity in this method to be more readable in the future.
5. Fix a computation issue in `_get_child_lines`. While iterating on move lines of a hide prices section, we were using the section total amount on each line, which is wrong in case we have subsections. For subsections, we need to recompute the amount to only include the subsection lines.
no-taskUsers will no longer receive two push notifications for the same message due to an incorrect notification preference check. The mail app now uses the right user preference source, making inbox notifications behave as expected.
Original PR description
**Current behavior before PR:** The `isInbox` condition was always evaluated as false because it incorrectly checked the user's notification preference in the wrong model. This caused users to receive two push notifications for the same message. **Desired behavior after PR is merged:** The `isInbox` condition now checks the user model for notification preferences, ensuring the correct behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233185
Customers who navigate back during checkout and choose a different delivery address are now handled safely instead of seeing an error page. If the cart is no longer available, the website redirects them back to the shop, preserving a smoother buying experience.
Original PR description
Currently, an error occurs when the user changing the delivery address in the website. **Steps to reproduce:** - Install the `website_sale` module and enable the `Demo` payment provider. - Go to `Website` > `Shop` > `Add a product to Cart` > `View cart` > `Checkout`. - Ensure there are at least two different delivery addresses > `Confirm` > `Pay now`. - Quickly press the browser’s `back button` twice. - Select a different `delivery address`. **Error:** `ValueError: Expected singleton: sale.order()` **Root Cause:** At [1], the code calls `order.ensure_one()`. When the cart (`sale.order`) is empty, leads to an `error`. **Fix:** This commit prevents a traceback on the frontend when a user attempts to change the delivery address and safely redirects them to the shop page. [1]: https://github.com/odoo/odoo/blob/88c9a45ee1ff8dde871865723c3387c059af8289/addons/delivery/models/delivery_carrier.py#L157 sentry-6869972801 Forward-Port-Of: odoo/odoo#226781
This fix stops users from adding tax tags to journal items dated before the tax lock date. It helps protect finalized tax reports from being changed after the reporting period has been locked.
Original PR description
Despite the tax lock date, users are able to modify the tax report by adding tags.
**Steps to reproduce:**
Ensure the tax lock date is set
1. Journal Items list view
2. Edit one/many lines that
- have a date before the tax lock date,
- don't have a tax,
- nor tax tags,
- and is not a tax line.
3. Add a new tax tag
**Issue:**
The tax tags are added and might impact a tax report, when you should have received a user error.
**Cause:**
The `write` function calls the `_check_tax_lock_date` which in turn only checks the existing line instead of the values given in the `write` parameters. Since the line has no existing tax tags the check does not fail.
**Solution:**
Call the tax lock check both before and after writing the move line.
Task-5169152
Forward-Port-Of: odoo/odoo#233032
Forward-Port-Of: odoo/odoo#232380