Tuesday, October 14, 2025
30 changes · 19.0
New functionality added to Odoo
Point of Sale restaurants using UrbanPiper can now connect with Keeta as an additional delivery provider. This expands available delivery channel options and helps businesses reach customers through another food delivery marketplace.
Original PR description
In this commit : - Integrated Keeta as a new food delivery provider in `pos_urban_piper`. Task - 5128817
Enhancements to existing features
The account merge process now gathers existing account codes in one database operation instead of checking each company one by one. This reduces waiting time when merging accounts, especially in databases with many companies.
Original PR description
The merge wizard needs to collect the account codes of the accounts we are merging in order to write them on the merged account as the final step of the merging process. At the moment, collecting the account codes is done in Python and loops over all the existing root companies, retrieving the code of the account for each company. On a recent l10n [runbot](https://runbot.odoo.com/runbot/build/90542336) (with 146 companies), this was causing the merging step to take ~4.5 seconds per account, most of this time being taken just by collecting the account codes. Instead, we collect the codes in a single SQL query. Flamegraphs: [before.json](https://github.com/user-attachments/files/22726956/before.json) [after.json](https://github.com/user-attachments/files/22726960/after.json) task-none Forward-Port-Of: odoo/odoo#230158
Resolved issues and error corrections
Fixes an issue where an invoice could link users to an older draft payment instead of the confirmed payment that actually settled it. This makes payment navigation from invoices more reliable, especially when payments are reset, duplicated, and reconciled again.
Original PR description
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having…
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having an outstanding account set - Use the smart button on the invoice form view to open the payment and reset it back to draft - Duplicate the payment, confirm the new one and reconcile it with the invoice => If we go back to the invoice form, the smart button linking payments is now redirecting to the 1st payment, that's in draft state, instead of the second confirmed one. This is because there can be 2 types of links between payments and invoices: - When there's no journal entry for payment, the link is done via the Many2many table 'account_move__account_payment'. - When there's a journal entry, the link is done via the table 'account.partial.reconcile'. Before this commit, the button on the invoice form view was based on account_move__account_payment and wasn't looking at all at account.partial.reconcile as one would expect. To solve that, we now look at reconciled_payment_ids that is computed as the union of account_move__account_payment and account.partial.reconcile. Task-4613193 Runbot: https://runbot.odoo.com/runbot/bundle/18-0-outstanding-double-link-roto-354130 Forward-Port-Of: odoo/enterprise#96927 Forward-Port-Of: odoo/enterprise#89089
This update improves performance when editing website and email content by avoiding unnecessary page recalculations. Users should notice smoother behavior in areas that update many page elements, such as the website builder, HTML editor, and product variant previews.
Original PR description
The goal of this commit is to improve performance when using setAttribute. Using the native setAttribute causes the layout to be recalculated each time it is used, even if the same value is set. We are therefore introducing the setAttribute utils, which will check that the value is different before applying it. These performance issues are noticeable in situations where many elements need to be modified. 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
Point of Sale orders received through Urban Piper can no longer be manually deleted. This helps keep online order records consistent with the normal cancellation or rejection process handled by the delivery aggregator or restaurant.
Original PR description
Before this commit: =================== - We were able to delete online orders, but generally, online orders are either cancelled by the aggregator or rejected by the restaurant. After this commit: ================== - Online orders can no longer be deleted. Task: 496669
The link editing popover now gives clearer visual feedback when users move through fields and buttons with the keyboard. Focus also stays inside the popover while tabbing, making link editing easier and more accessible.
Original PR description
Steps to Reproduce: - Select a word in the editor. - Press Ctrl + K and Enter to open the link popover. - Use the Tab key to move between the fields and buttons. Current behavior before PR: - It was not clear which field had the focus. - The border was always overridden by the `border-dark-subtle` class with `!important`, so users had no visual feedback when tabbing. - When tabbing, focus could escape the link popover instead of looping inside it. Desired behavior after PR is merged: - Inputs and selects now use the correct border color on focus, aslo discard button changes opacity when focused. - The link popover traps focus: pressing Tab/Shift+Tab will cycle through focusable elements without leaving the popover. task-4965566 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223868
Fixed an accounting issue where an invoice could link to an old draft payment instead of the confirmed payment that actually settled it. This helps users reliably access the right payment record from invoices, reducing confusion during payment follow-up and reconciliation.
Original PR description
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having…
[FIX] account: set correct links between invoices and payments The problematic found case was the following: - Create an invoice and register a payment for it, using the wizard, with a journal having an outstanding account set - Use the smart button on the invoice form view to open the payment and reset it back to draft - Duplicate the payment, confirm the new one and reconcile it with the invoice => If we go back to the invoice form, the smart button linking payments is now redirecting to the 1st payment, that's in draft state, instead of the second confirmed one. This is because there can be 2 types of links between payments and invoices: - When there's no journal entry for payment, the link is done via the Many2many table 'account_move__account_payment'. - When there's a journal entry, the link is done via the table 'account.partial.reconcile'. Before this commit, the button on the invoice form view was based on account_move__account_payment and wasn't looking at all at account.partial.reconcile as one would expect. To solve that, we now look at reconciled_payment_ids that is computed as the union of account_move__account_payment and account.partial.reconcile. Task-4613193 Runbot: https://runbot.odoo.com/runbot/bundle/18-0-outstanding-double-link-roto-354130 Forward-Port-Of: odoo/odoo#231148 Forward-Port-Of: odoo/odoo#202076
Batch sending invoices now correctly applies Peppol only to invoices that are eligible for it. This prevents invoices meant to be sent by email, such as those for non-Peppol customers, from failing and blocking their email delivery.
Original PR description
…ng methods When sending invoices in batch with multiple sending methods (for example 1 by Peppol, 2 by Email), Peppol was wrongly set on invoices where it didn't make sense. Steps to reproduce: 1. Go into a Peppol compatiable company (Eg: Belgium) 2. Go into settings, enable Peppol. 3. Create & post two invoices: one to an US partner, the other one to a Peppol partner (For example a belgian partner with a vat set.). Make sure to set the email on both. 4. Send them in batch: the wizard says 1 by Peppol, 2 by Email, which is correct. 5. If you send them, the one to the US partner that is not supposed to go through Peppol will end up in error, with the email not sent either. Root cause: We are doing some Peppol checks before checking if it actually make sense to apply this sending method on the move. task-none (reported from our production) Forward-Port-Of: odoo/odoo#230880
The Subscriptions MRR Breakdown report now only considers active companies when preparing its data. This prevents an access error that could appear in multi-company setups after archiving an old company and changing currencies, allowing users to open report details reliably.
Original PR description
Step to reproduce: - Start database without demo data and install Subscriptions - Create a new Company and archive the first Company in the Database - Set a currency rate on a currency (i.e. Euro),…
Step to reproduce: - Start database without demo data and install Subscriptions - Create a new Company and archive the first Company in the Database - Set a currency rate on a currency (i.e. Euro), then set that currency as the Main Currency of the new Company. - Then, set a currency rate on the previous Main Currency i.e USD. - Create a Subscription Sales Order and confirm it. - Open the MRR Breakdown report. - Click into the data of the report. Observation: An error message will occur appear (Access Error) Issue: - when building the query, it also fetches the archived company, due to `active_test` context applied from [fetch()](https://github.com/odoo/odoo/blob/754599a7720ee179fc5304b9613df9c177e4b231/odoo/models.py#L3858), and hence wrong query is build which fetches no data, leading to sort of access error as this [condition](https://github.com/odoo/odoo/blob/754599a7720ee179fc5304b9613df9c177e4b231/odoo/models.py#L3876) matches. Fix: - we explicitly search for active companies opw-5090463 Forward-Port-Of: odoo/enterprise#95989
This fixes an error that could prevent Odoo from starting or handling URL-related operations when running on Python 3.11 or newer. The change improves compatibility with newer Python environments and avoids disruption caused by a missing dependency constant.
Original PR description
Closes #230990 Description of the issue/feature this PR addresses: - In Python 3.11+, urllib3 stopped relying on its internal _WHATWG_C0_CONTROL_OR_SPACE constant directly in newer releases Current behavior before PR: - As described by #230990 Desired behavior after PR is merged: - Using Python 3.11+ should not throw a _WHATWG_C0_CONTROL_OR_SPACE missing error --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Payment terminal transactions in Point of Sale now complete automatically when cash rounding is applied. This reduces the risk of staff needing to manually validate already-paid orders, helping avoid missed validations and checkout mistakes.
Original PR description
Ensure that when a payment is made via a payment terminal and cash rounding is applied, the payment is automatically validated once the response is received. Previously, validation did not always occur because we relied on `get_due` is not exactly what is left to pay, as it does not account for cash rounding rounded amounts. The condition for auto-validation was simplified, since `is_paid` already checks whether there is nothing left to pay. Thus, using `get_due` is redundant. Steps to reproduce: 1. Create a cash rounding and set it on the POS. 2. Sell a product priced at e.g. 1.99 EUR, paid via a terminal (e.g. Worldline). 3. Notice the payment is not auto-validated and requires manual validation, which can lead to mistakes or missed manual validations. opw-4862684 Forward-Port-Of: odoo/odoo#231153 Forward-Port-Of: odoo/odoo#228608
This update fixes visual alignment in blog list cards and keeps selected tag filters when date filters are changed or cleared. It helps website visitors and editors get more consistent blog navigation without losing their chosen filters.
Original PR description
This PR addresses the following issues: **Issue 1: Date Misalignment** **Steps to Reproduce:** 1. Navigate to website → Blog Page → Edit. 2. Change the layout from Grid to List. 3. Toggle the Cards…
This PR addresses the following issues:
**Issue 1: Date Misalignment**
**Steps to Reproduce:**
1. Navigate to website → Blog Page → Edit.
2. Change the layout from Grid to List.
3. Toggle the Cards button on.
4. The date and tags will appear slightly misaligned.
**Solution:**
Adding `#{` code in the `t-attf-class` attribute will align the date with the blog post content and tags.
**Expected Behavior:**
The date should align with the blog post content and tags preview.
**Issue 2: Some Tag Filters Getting Removed**
**Steps to Reproduce:**
1. Add a date filter from the sidebar of the blog.
2. Remove this filter by clicking the X button.
3. If multiple tags are present in the filter section, only the first tag remains while the rest are removed when the date filter is added or removed.
**Solution:**
Sending a POST request whenever the date filter is selected or removed. To achieve this, we introduced the `post_link` class to the `<select>` and `<a>` elements. When a date option is chosen, the click event triggers the `_onClickPost` handler
function, which extracts the URL from the `value` attribute of the `<option>` tag.
**Expected Behavior:**
All previously added tags should remain after adding or removing the date filter.
**Issue 3: All Tag Filters Getting Removed**
**Steps to Reproduce:**
1. Navigate to website → Blog Page → Turn On the Sidebar.
2. Select any tag from the tags section in the sidebar.
3. Ensure no blog is selected.
4. Select a date from the archives in the sidebar.
5. Change the date to '-- All Dates' in the archives dropdown.
6. All tags in the filter are removed along with the date.
**Solution:**
Removing the condition for navigation based on whether a blog is present or not will ensure tags remain in the filter section after selecting the '-- All Dates' option.
**Expected Behavior:**
Tags present in the filter section should remain after selecting the '-- All Dates' option.
task-3937884
Forward-Port-Of: odoo/odoo#230592
Forward-Port-Of: odoo/odoo#225845UrbanPiper POS orders now apply the correct taxes when a store operates under a branch company. This prevents missed taxes on order lines and improves accuracy for businesses using multi-branch setups, including cases where taxes are split into sub-taxes.
Original PR description
Steps to reproduce: --- - Install `pos_urban_piper`. - Create a branch under *Main Company*. - Switch to the new branch. - Create a POS config in this branch and set up UrbanPiper. - Sync "Apple Pie". - Place an order with "Apple Pie". Issue: --- - The 15% tax defined on Apple Pie is not applied on the orderline. Cause: --- - While creating the order line, the tax company was compared directly with the POS config’s company. In this case, the tax belongs to the parent company, while the POS config belongs to a child company. Fix: --- - Compare the `root_id` of both companies instead of the direct company ID to ensure taxes are applied correctly in multi-branch setups. - Additionally, handled the case where a main tax has sub-taxes (e.g., 5% GST split into 2.5% SGST and 2.5% CGST). In such cases, we now fetch the tax type from the sub-taxes instead of the main tax. Task-5050682 Forward-Port-Of: odoo/enterprise#96672 Forward-Port-Of: odoo/enterprise#93467
Invoices eligible for early payment discounts now remain marked as partially paid when only part of the amount is paid. This prevents unpaid balances from being incorrectly moved to a suspense account, improving payment accuracy and receivables reporting.
Original PR description
Problem: If partial payment is done for Invoice which is eligible for early payment discount, Invoice is marked as paid and remaining amount is debited in suspense account. Cause: While preparing credit entry for receivable account, only eligibility of Invoice for early payment discount was checked and whole residual amount of Invoice is credited instead of amount which is paid, and this is done for partial payments also(which shouldn't be done). After this commit: If partial payment is done for Invoice which is eligible for early payment discount, Invoice is marked as partially paid and only amount which is paid is credited from receivable account and nothing in suspense account. task-5128802 Forward-Port-Of: odoo/enterprise#95994
This fix prevents the Point of Sale configuration from entering an endless update cycle when no default or available preset is set. It helps ensure POS settings can be saved reliably in empty or newly configured setups.
Original PR description
The condition `config.default_preset_id.id not in config.available_preset_ids.ids` is equivalent to True when both default_preset_id and available_preset_ids are empty. This triggers an infinite loop as assigning with `|=` triggers a nested write. 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
Recruitment users can now add applicants to a talent pool without being blocked by employee access permissions. This prevents an unnecessary error and keeps the talent pool workflow usable for recruiters with limited employee data access.
Original PR description
Steps to reproduce: ==================== 1. Grant admin access for Recruitment to demo user. 2. Go to the Recruitment app. 3. Open Applications > Talent Pool. 4. Select a talent pool. 5. Click "Add to pool". Problem: ========= If the user lacks read access on Employees, an access error occurs. This happens because `_add_applicants_to_pool` tries to access `proposed_contracts`, https://github.com/odoo/enterprise/blob/95b9942316c962950ace6b899faa6f1e6c8fee9a/hr_contract_salary/models/hr_applicant.py#L17 which triggers a read on `hr.version`. Since `hr.version` uses `_order`, https://github.com/odoo/odoo/blob/f0eb0c792b77fbaf0ef3738ea88d9c2bae880a85/addons/hr/models/hr_version.py#L28 it tries to sort the result, leading to a access rights error. Fix: ==== Use `sudo` when calling _add_applicants_to_pool. opw-5074018 Forward-Port-Of: odoo/odoo#227246
CRM and subscription spreadsheet dashboards now calculate key totals correctly and load the sales pipeline view with a more relevant recent-time filter. This improves dashboard accuracy and makes record drill-downs less likely to apply unintended filters or defaults.
Original PR description
See commit messages
The Point of Sale checkout now handles repeated selection of an online payment method without crashing. This prevents interruptions during payment processing and helps cashiers complete sales smoothly.
Original PR description
Steps to Reproduce(On Runbot): - Navigate to Pos>Configuration>Payment Method - Create an 'Online Payment' method using 'Demo Payment' for a shop (e.g., bakery shop). - Open a session for the bakery shop, select any product, and proceed to payment. - Select the online payment method multiple times. Error: `TypeError: Cannot read properties of undefined (reading 'currency')` After this commit: - Users can select the payment method multiple times without a crash. task-5122932
The Point of Sale flow now stops order validation when a cashier cancels the required customer popup for Customer Account payments. This prevents incomplete orders from causing an error and keeps the checkout experience stable.
Original PR description
Steps to reproduce: =================== - Open POS and add a product to the cart - Go to the Payment screen - Select `Customer Account` as the payment method and Validate Order - The `Customer Required` popup appears - Click `Cancel` on the popup Issue: ====== - POS still continues with the order validation process - This leads to a traceback since the order data is incomplete Cause: ====== - The `_askForCustomerIfRequired()` always returned a value that allowed validation to continue - As a result, validation continued even after clicking Cancel Fix: ==== - `validateOrder()` now checks the return value and aborts validation if the user cancels the popup Task: 5094722
Opening a manufacturing Bill of Materials overview could fail when Odoo tried to plan a very large producible quantity beyond work center capacity. The system now falls back to the actually requested quantity, allowing users to view the overview and continue replenishment planning.
Original PR description
### Steps to reproduce: 1. Install mrp + purchase 2. Create a new product (A) 1. Add the Buy route on the product 2. Add a vendor line on the Purchase tab 3. Set the quantity on hands to 2000 3.…
### Steps to reproduce: 1. Install mrp + purchase 2. Create a new product (A) 1. Add the Buy route on the product 2. Add a vendor line on the Purchase tab 3. Set the quantity on hands to 2000 3. Create a second product (B) with manufacturing route 4. Create a BoM for this product (B) 1. Add the product (A) as the component with 1 quantity 2. Create a new operation with a duration of 600:00 5. On the product B's page, click Replenish 1. Put 10 quantities to replenish 2. Select the manufacturing route and confirm 6. Go to the BoM and open the BoM overview 7. 'Impossible to plan. Please check the workcenter availabilities.' https://github.com/user-attachments/assets/58697fd9-4e3e-4df6-98e1-5de7e8759715 ### Before this commit: When opening the BoM overview, if the producible quantity for this BoM exceed the quantity we can plan in the 700 following days, an error is displayed. ### After this commit: If the quantity producible cannot be planned, we retry automatically with the requested quantity. opw-5031724 Forward-Port-Of: odoo/odoo#229745 Forward-Port-Of: odoo/odoo#227433
The QR Menu for Belgian blackbox-enabled Point of Sale setups no longer shows a blank page when the register session has not been opened. This ensures customers can still view the digital menu as expected, avoiding lost service availability before the PoS session starts.
Original PR description
When you open the QR Menu of a PoS that uses the blackbox, the menu will not appear if the session is not opened. Steps to reproduce: ------------------- * Setup a PoS to use the blackbox * Setup the same PoS to use the QR Menu * Try to open the menu without opening the PoS > Observation: The QR Menu never show anything, the page stays blank. Why the fix: ------------ Here (https://github.com/odoo/enterprise/blob/0635388bdc9f115d527e0d2da43dfcd0d4a00d1f/pos_blackbox_be/static/src/self_order/overrides/services/self_order_service.js#L61-L62) if the session is not opened, we try to read `_product_product_work_in` on session that is undefined. opw-4829700 Forward-Port-Of: odoo/enterprise#93196
Fixed an issue where point of sale quick-add payment buttons such as +10 or +50 could calculate wildly incorrect amounts for users in languages that use a comma as the decimal separator. This ensures cashiers can rely on the buttons to add the intended payment amount, reducing checkout errors.
Original PR description
**Steps to reproduce:** - Set your database in a language with a "," as a decimal separator, such as French - Make a purchase, chose a payment method - Before paying, click any +10/20/50 button - The…
**Steps to reproduce:** - Set your database in a language with a "," as a decimal separator, such as French - Make a purchase, chose a payment method - Before paying, click any +10/20/50 button - The price will be multiplied by 100, then add the desired amount **Why the fix:** There were two places where the decimal separator was causing issues. First when we try to get the current price, *currentBufferValue*, we try to get it when it's in float state, but as we have a language with a decimal separator set as "," the "." in this float will be ignored, and we will take the decimal as units as well, explaining the *100 amount, because the decimals become whole numbers. Secondly, when we try to make the addition of the two and convert it to string again, the *toString* method will convert it with a default "." not taking the current decimal separator into account. Once again, the "." will be ignored later on, leading to an even more over the top number. We now convert the numbers and the strings using the correct decimal separator. opw-5126224 Forward-Port-Of: odoo/odoo#229735
This fixes a crash that could happen when a user hid an HTML field while newly added images were still being processed. The editor now preserves the content safely during that delay, helping users avoid interruptions and potential lost edits.
Original PR description
**PROBLEM** When hiding a HtmlField field from a view with pending images in it, there is a traceback. **STEP TO REPRODUCE** 1. Using studio, create a HtmlField on the view of your choice. 2. Add a…
**PROBLEM** When hiding a HtmlField field from a view with pending images in it, there is a traceback. **STEP TO REPRODUCE** 1. Using studio, create a HtmlField on the view of your choice. 2. Add a checkbox next to it, and link the HtmlField visibility to the button. 3. Add a image to the HtmlField (don't save the record !) 4. Hide the HtmlField using the checkbox, there should be a traceback. (if not, try with a bigger image). **CAUSE** commitChanges() will try to retrieve the field value to commit by looking at the related element in the DOM. Before retrieving this value, we call savePendingImages() to save the new images added to the HtmlField. https://github.com/odoo/odoo/blob/1416aad902a97ce56aaecc2aadc4dd9f7814ee53/addons/html_editor/static/src/fields/html_field.js#L159-L162 This introduces a delay, during which the DOM element could be destroyed. **FIX** We don't call commitChanges() in OnBlur(). Instead, we cache the new value in a property of HtmlField called `newValue` when `OnChanges()` is called. Inside OnBlur(), we save the pending images by directly calling `savePendingImages()` and we commit the new value by calling `updateValue(this.newValue)` opw-5061820 Forward-Port-Of: odoo/odoo#230980 Forward-Port-Of: odoo/odoo#227482
Discuss now handles encrypted or unreadable PDF attachments without showing an error. Users can continue uploading files normally, while invalid previews are handled gracefully instead of interrupting their workflow.
Original PR description
Currently, an error occurs when trying to preview the first page of a PDF attachment in Discuss if the PDF is `encrypted` or contains `invalid encoding`. **Steps to produce:** - Install the `mail`…
Currently, an error occurs when trying to preview the first page of a PDF attachment in Discuss if the PDF is `encrypted` or contains `invalid encoding`. **Steps to produce:** - Install the `mail` module. - Open `Discuss` and attach the encrypted file [1], or the invalid PDF file [2]. (`Note`: Ensure Python version 3.12+ is used.) **Error:** `PyPDF2.errors.DependencyError: PyCryptodome is required for AES algorithm` `UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa4 in position 0: invalid start byte` **Root cause:** At [3], `extract_page` directly calls `PdfFileReader`, when it fails to read or decrypt the file, Python raises an error. **Fix:** This commit prevents errors when a user attaches a PDF file that is unreadable or encrypted. [1]: https://drive.google.com/file/d/1moSlwXHkqcV6_7zHBNhLMLi-9Ye_xDGJ/view?usp=sharing [2]: https://drive.google.com/file/d/16O4LLH8dL0RWmbOx4HrcooFUyesWaVi-/view?usp=sharing [3]: https://github.com/odoo/odoo/blob/11cbbb85b1ee2a620d752b79e86fc51a8e3b33e4/odoo/tools/pdf/__init__.py#L227 sentry-6912765819
The duplicate transaction warning in bank reconciliation was not taking users to the tool for finding duplicates. This fix restores that link, helping accounting users quickly review and resolve possible duplicate bank transactions.
Original PR description
Before this commit, the action "Some transactions may be duplicates." was broken because 2 elements from the old bank reconciliation widget were removed. The commit [[1]] of the new bank reconciliation widget forgot to add the action service and a link to the journal. These 2 elements were used to redirect the customer to the Find duplicates tool. This commit adds, in the extension of the bank reconciliation kanban controller, the call to the action service and adapt the old code to match the new one. no task id [1]: https://github.com/odoo/enterprise/commit/2335c953723dce66af8811fdfbfd5b811d42b109 Forward-Port-Of: odoo/enterprise#96849