Daily updates from Odoo
Monday, July 28, 2025
133 changes
47 changes
Resolved issues and error corrections
The website editor now shows saved carousel transition speeds using the correct unit when reopened. This prevents confusing values such as 1000 seconds appearing instead of 1 second, helping users confidently edit saved page settings.
Original PR description
This commit fixes a bug where the value of a BuilderNumberInput would not load with the assigned unit of measure. Steps to reproduce - add a carousel snippet - edit Transition/Speed to be 1s - save - the speed is correctly saved as 1000ms - reopen editor and check the carousel snippet again => the speed is 1000s instead of 1s
When a server action raises a warning, users will now see a clear, friendly dialog instead of a technical traceback. This makes the error easier to understand and helps users know what happened without needing developer support.
Original PR description
### Description of the issue/feature this PR addresses: https://github.com/odoo/odoo/commit/ef4c1350df10c186efec79b1414306e325707549 introduced a new exception `ServerActionWithWarningsError`:…
### Description of the issue/feature this PR addresses: https://github.com/odoo/odoo/commit/ef4c1350df10c186efec79b1414306e325707549 introduced a new exception `ServerActionWithWarningsError`: https://github.com/odoo/odoo/blob/851c46923332aa13c56fbce3a5ed3c5d37a70c92/odoo/addons/base/models/ir_actions.py#L486-L488 This was not registered as an error_dialog. This led to the frontend displaying the entire traceback instead of an error dialog similar to `UserError` when a `ServerActionWithWarningsError` is raised. This commit fixes it by correctly registering the error in `error_dialog` registry category so a more user friendly dialog is displayed with the error contents. Thanks @brboi for helping with the fix ### Current behavior before PR: A traceback error is thrown when a `ServerActionWithWarningsError` is raised. Example: <img width="1896" height="904" alt="image" src="https://github.com/user-attachments/assets/0bfee329-e6c5-4652-a2ac-d41b763e2bdb" /> Video reproducing it: https://drive.google.com/file/d/1C_aE0d_9bP27f388dB1NJLeWHBpsM7AW/view?usp=drive_link (credits: gavb-odoo) ### Desired behavior after PR is merged: An error dialog similar to UserError which is easier to understand is displayed <img width="1906" height="799" alt="image" src="https://github.com/user-attachments/assets/d57c5cab-14f2-4f39-9f0c-b8099e8b0089" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr opw-4885670 Forward-Port-Of: odoo/odoo#219977
Accounting journal sequence prefixes that include Greek letters can now be used without causing invoice confirmation errors. This prevents disruptions for businesses using European communication standards and localized document numbering.
Original PR description
**Issue** Using a Greek letter in the journal's sequence prefix causes a traceback error when confirming an invoice **Steps to Reproduce** 1. Install the Accounting module 2. Navigate to Accounting >…
**Issue** Using a Greek letter in the journal's sequence prefix causes a traceback error when confirming an invoice **Steps to Reproduce** 1. Install the Accounting module 2. Navigate to Accounting > Configuration > Journals 3. Open the Sales journal 4. Under the Advanced Settings tab, set the communication standard to "European" 5. Set the sequence prefix to include Greek letters (e.g., "TΠY") 6. Create and confirm a new invoice 7. Observe the traceback error **Root Cause** The prefix is used in calculating the `check_digits` via a base-36 to base-10 conversion. This conversion fails for Greek characters, which are not valid in base-36, leading to an exception **Fix** Greek letters in the prefix are transliterated to their Latin equivalents before performing the checksum calculation, ensuring compatibility with the base-36 conversion logic Opw-4813790 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#212169
Newsletter signup forms now work correctly when Cloudflare Turnstile is enabled on a website. This prevents page errors and ensures visitors can subscribe without the anti-spam protection breaking the form.
Original PR description
Forward-port of: 10550b3c7ad607576dc48eeba4d601184a2f90d4 Scenario: - configure turnstile in setting - install website_mass_mailing - drop the newsletter widget in any page Result: In saas-18.3 and…
Forward-port of: 10550b3c7ad607576dc48eeba4d601184a2f90d4 Scenario: - configure turnstile in setting - install website_mass_mailing - drop the newsletter widget in any page Result: In saas-18.3 and over, we get this traceback error and the turnstile code is not working: TypeError: Cannot destructure property 'turnStile' of 'odoo.loader.modules.get(...)' as it is undefined. Cause: - On January 2025, in saas-18.2 and over, 421c5e5c4ee6271bb1085b43505cc1c28b2cb574 and 22e777c046521f3f89b62caa5876680beb7f5aba rewrote turnstile - On April 2025, in 17.0 up to master, c48e74f57569a1670fee65d65625488846513d79 uses addTurnstile and addSpinner method and the old file - On April 2025, in saas-18.2 and only saas-18.2, 10550b3c7ad607576dc48eeba4d601184a2f90d4 fixes turnstile for the interaction rewrite So turnstile still cause an error with the newsletter widget in saas-18.3 up to master. Fix: forward-port the saas-18.2 10550b3c7ad607576dc48eeba4d601184a2f90d4 fix in following versions. opw-4925771 opw-4933957 Forward-Port-Of: odoo/odoo#219255
Foreign customers without a state are now correctly treated as overseas customers when creating Indian invoices and sales orders. This prevents them from being assigned the company’s Indian state, helping ensure accurate GST tax treatment and compliance.
Original PR description
Before this PR: When creating invoices/orders for foreign customers that don't have states defined in their country, both **account.move** and **sale.order** models would incorrectly assign the…
Before this PR: When creating invoices/orders for foreign customers that don't have states defined in their country, both **account.move** and **sale.order** models would incorrectly assign the company's Indian state as the place of supply. This happened because the fallback logic would always use **move.company_id.state_id** without checking if the partner was actually Indian. As a result, foreign customers would be treated as Indian customers in GST calculations, leading to incorrect tax treatment and compliance issues. After this PR: Both models now correctly identify foreign customers by checking the partner's country first, before falling back to state-based logic. Foreign customers without states are now properly assigned the foreign state reference (**l10n_in.state_in_oc**) instead of the Indian company's state. This ensures accurate GST treatment where foreign customers are correctly identified as overseas transactions. Task-4900697 Forward-Port-Of: odoo/odoo#220717 Forward-Port-Of: odoo/odoo#216220
The stock serial number generation wizard now only shows unit-of-measure information when that option is enabled. This prevents an error for users creating serial or lot numbers when unit-of-measure settings are not active.
Original PR description
Previous to this commit, the generating serial wizard would try to load the product uom in case that the product was lot-tracked, even if the UoM group was not activated. This led to an error when opening the wizard without activating the group. This commit makes sure the group is activated before showing that field. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Recruitment users can now refuse a newly created applicant even if no applicant name has been entered. This prevents an error from interrupting the refusal workflow and keeps application management running smoothly.
Original PR description
Currently, an error occurs when refusing an applicant. Steps to Reproduce: - Install the `hr_recruitment` module. - Go to `Recruitment` > `Applications` > `All Applications`. - Click `New`, then click `Refuse`. `TypeError: sequence item 0: expected str instance, bool found` This error occurs when refusing an applicant who does not have an applicant name. It tries to access partner_name or display_name, but since it is False, the join raise the error[1]. This commit ensures that if the partner name is present, it is added; otherwise, an empty string is added. [1]- https://github.com/odoo/odoo/blob/ca90fd17b2c50651d698e6e0e3065ba978b06d01/addons/hr_recruitment/wizard/applicant_refuse_reason.py#L52 sentry-6740479737 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The recruitment app now disables the copy email button until a new tracker record has been saved. This prevents users from encountering an error when creating recruitment source trackers and improves reliability during hiring setup.
Original PR description
Currently an error occurs when user try to copy email on a newly created record. Steps to reproduce: - Install `hr_recruitment`with demo data. - Add a random Alias Domain (`Settings > Technical >…
Currently an error occurs when user try to copy email on a newly created record. Steps to reproduce: - Install `hr_recruitment`with demo data. - Add a random Alias Domain (`Settings > Technical > Email > Alias Domains`). - Open `hr_recruitment` and on 'Experienced Developer', open the option dropdown (meatball) and click on 'Trackers'. - Now click on `New` and click the copy email button (without saving). Error: `ValueError: Expected singleton: hr.recruitment.source()` Cause: - Error occurs due to a recent change in this [commit](https://github.com/odoo/odoo/pull/198995/commits/f8cf1b70e28166c100558d2bf5cbc6d8d3513cc6) that introduced the new copy widget - The error occurs because the function was called even before the record was saved. This caused the function call to be made with empty recordset that causes the singleton error at line [1]. Solution: - Made the copy button disabled until record is saved. [1]: https://github.com/odoo/odoo/blob/679d99b8bd233a1046e3219ddb3e23e8465f6107/addons/hr_recruitment/models/hr_recruitment_source.py#L49 sentry-6753165441 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Website charts now automatically assign a visible color when a new dataset column is added. This restores the expected editing behavior so users do not see transparent or missing chart colors after adding data.
Original PR description
Before [the refactoring of the html_builder], [0,0] cell was selected by default and the selected cell was kept when we switched the chart type. Now, this was lost in the refactoring. [the refactoring of the html_builder]: https://github.com/odoo/odoo/commit/9fe45e2b7ddb Related to task-4367641
Website editors can now move the last block from one table of content into another without triggering an error. This prevents an editing interruption and makes page building more reliable.
Original PR description
Since [1], a traceback appears when we drag the last block of a table of content into another one. Drag and drop two tables of content on the website page One by one, drag and drop the blocks from the second table to the first one traceback for the last one... This commit resolves the issue [1]:https://github.com/odoo/odoo/commit/6cd9606e285741b59042b9674bf6682273c43a69 task-4144022 Forward-Port-Of: odoo/odoo#180039
This fixes an issue where the same point of sale order could be sent to preparation printers from multiple devices, causing duplicate tickets. The system now checks whether an order was already sent and synchronizes updates after printing, reducing confusion for staff and avoiding repeated preparation work.
Original PR description
Before this change, when a device sent an order in preparation via the ticket printer, this could result in the same order being printed by multiple devices, as the order was not synchronized after it was sent. The error is a bit tricky, because if the user had installed a preparation screen, the order was sent to the preparation screen via syncAllOrders. In this case, the order was correctly synchronized and the other devices were informed of the changes. This commit adds two things. - We check the server before sending the order to preparation to make sure it has not already been sent. - Even when the user does not have a preparation display, the order will be synchronized after being sent to a printer. Forward-Port-Of: odoo/odoo#220716 Forward-Port-Of: odoo/odoo#220535
This fixes an issue where some point-of-sale orders could not be invoiced after session closing when cash rounding was enabled only for cash payments and the order used mixed payment methods. Businesses can now invoice these posted POS orders without accounting imbalance errors.
Original PR description
Before this commit, an imbalance entry error occurred when invoicing a posted order under specific conditions. This issue arose when cash rounding was enabled only for the cash payment method, but the order was paid using both bank and cash. For example, if an order had a total of 12.91, and was partially paid with a bank transfer of 15.59, resulting in a cash return of -2.70, the session could be closed. However, attempting to invoice this order after closing the session would fail due to the imbalance. opw-4912399 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218430
This update removes an unnecessary database index for project collaborators because an existing uniqueness rule already supports the same lookup need. It reduces redundant database maintenance with no expected change to user-facing project behavior.
Original PR description
There is a unique constraint `_unique_collaborator`, whos first key is `project_id`, which will cover the necessity for an explicit index on `project_id` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220595
The Calendar app's “Attending?” filter now correctly finds events based on the current user's attendance status, such as declined invitations. This prevents empty search results and helps users reliably manage their calendar events.
Original PR description
The filter on an event's "Attending?" status was not working correctly. When filtering, the search would always return an empty result set because the underlying search implementation was logically flawed. It incorrectly compared calendar.event IDs with calendar.attendee data, which could never match. This commit corrects the `_search_current_attendee` method to properly query the `calendar.attendee` model. It now finds the intersection of attendees that both belong to the current user and match the filter criteria (e.g., state is 'declined'). It then uses these results to return the correct parent calendar events. A unit test has been added to verify the filter now works as expected. opw-4892386 Forward-Port-Of: odoo/odoo#218878
This fix helps IoT boxes start correctly when connected to older Odoo versions and reduces early connection failures caused by incorrect device time. It also makes certificate downloading more tolerant of slow networks and prevents Wi-Fi update errors when no IP address is available.
Original PR description
This commit fixes the following issues: - The hw_drivers and hw_posbox_homepage folders were missing from the sparse checkout, meaning that connected to version prior to 18.4 would prevent Odoo from starting. - As the IoT box can only sync time with the network once it gets an internet connection, some early requests could fail due to it thinking the SSL certificates were invalid. We disable verification of the requests to bypass this. - The request to download the certificate for the IoT box only had a timeout of 5 seconds, sometimes this could not be enough so the timeout has been increased to 10 seconds. - Fix an error when calling the `update_wifi` route, caused by `helpers.get_ip()` now being able to return `None`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale invoices now use the bank account configured on the selected payment method when available, instead of always using the company's default partner bank account. This ensures customers receive invoices with the intended payment details and reduces payment routing mistakes.
Original PR description
When generating an invoice for a PoS order we were never using the bank account set on the payment method, but always the one set on the company partner. Steps to reproduce: ------------------- * Create two bank account A and B * Set the bank account A as the company partner bank account * Set the bank account B on any payment method journal * Open PoS and create a new pos_order * Go to the payment screen and check the invoice button * Pay using the payment method linked to bank account B > Observation: The generated invoice will use bank account A Why the fix: ------------ We first try to use the bank account set on the payment method journal if none is present we fallback on the one set on the company partner. opw-4705497 Forward-Port-Of: odoo/odoo#220256 Forward-Port-Of: odoo/odoo#214523
After users upload or drop documents in Expenses, the upload drop area is now hidden instead of remaining on screen. Users are also taken back to the expense list so they can see the created expenses, even if document recognition fails.
Original PR description
When dropping documents on Expense, the drop zones would stay being displayed. We now stop to display it when a file is uploaded / dropped. task-4942503 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218812
This fixes an issue where customers who paid online through self-ordering could see the same order again as unpaid after the point-of-sale session was reopened. The self-order data is now synchronized with the server so payment status stays accurate across sessions.
Original PR description
If you paid for an order in self-order mode with an online payment method, then close the session and open a new one. The paid order would appear again in the self-order as not paid. Steps to reproduce: ------------------- * Setup a PoS with self-ordering and online payment method. * Open mobile menu and create a new order. * Add a product and pay for the order. * Close the session and open a new one. * Open mobile menu. > Observation: The order you just paid for appears again. Why the fix: ------------ When reading user data from server we should synchronise them with the indexedDB that still contains the old order that is not paid. Note: ---------- I was not able to come up with a test because the indexedDB is not kept between 2 tours. opw-4819672 Forward-Port-Of: odoo/odoo#219258
This update prevents errors when users replace an image with a caption and then edit that caption. It also avoids confusing editor tooltips appearing over images by keeping nearby content blocks properly formed when captions are added.
Original PR description
**Current behavior before PR:** - Replacing an image that has a caption, then editing the caption and clicking outside it, would result in a traceback. - When a caption was added to an image, the previous sibling block of the image became empty. As a result, the tooltip of that empty block could appear hovering above the image. **Desired behavior after PR is merged:** - A traceback no longer occurs when the image is replaced and the caption is edited before clicking outside. - If the previous sibling block is found to be empty when a caption is added, a `<br>` element is inserted into it. This ensures the block is no longer considered empty, preventing the tooltip from appearing above the image. task: 4876199
This fix lets website editors change or remove text animations even when their cursor is placed inside the animated text without selecting the whole word. It reduces repeated attempts and makes editing animated website content more predictable.
Original PR description
> [VBAL] Toolbar: Add an animation on some text > Try to remove it --> the animation stays on the end of the word, have to repeat x times to get rid of it Since 8c5e3d745b80c61332dbb814e622294d047e2576, it is possible to change an existing highlight when the selection is collapsed and inside it. The same thing is enabled for animated text, which allows to remove the animation options from the sidebar for animated text task-4367641
This update adjusts how background shape options behave in the website builder and adds test coverage for related builder controls. It helps ensure users can configure page backgrounds more reliably when editing website content.
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
This fix ensures products with variant options can still be sold in Point of Sale after an attribute line is removed. It prevents valid product combinations from being incorrectly treated as unavailable, reducing sales disruption at checkout and self-ordering points.
Original PR description
Before this commit, removing an attribute line from a product would inadvertently prevent the sale of any combination in the PoS interface. opw-4947529 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219251
This fixes an issue where the website editor toolbar could leave unnecessary blank space below the page footer, even when the toolbar was hidden. The toolbar now stays correctly positioned outside the page layout, improving page rendering and avoiding confusing extra whitespace.
Original PR description
Description of the issue/feature this PR addresses: - Commit [189a7c96](https://github.com/odoo/odoo/commit/189a7c96e6e26825dc05c0c6466576fe63aa091e#diff-de0d67e89972b45b101a9c4b04f316824314b0d69aba6208528586f1edb4f01cL25-L40) moved scrollbar from `#wrapwrap` element to `<body>`, caused the space below the footer visible for the floating toolbar. Current behavior before PR: - Space below the footer was always visible, even when the toolbar was hidden. Desired behavior after PR is merged: - `top: 0;` is applied on `.oe-toolbar` to ensure it stays out of the layout flow. - This prevents unnecessary layout space and ensures correct toolbar positioning. task-4652202 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217270
This update makes an automated website builder test more reliable by ensuring test timing is fully controlled during execution. It reduces random test failures caused by high system load, helping maintain smoother development and release validation.
Original PR description
Hoot provides us with "time control" features such as "advanceTime", which is useful for testing scenarios where we want to wait for some events to happen (such as a debounced function), but without…
Hoot provides us with "time control" features such as "advanceTime", which is useful for testing scenarios where we want to wait for some events to happen (such as a debounced function), but without actually waiting too much. The way it works is that hoot simply override setTimeout and related functions to keep track of all handlers and their scheduled time. However, this is not enough, as the real setTimeout is still by default called, so it can happen in some tests that when we advance the time by some amount, say 500ms, if the cpu load is very high, then other handlers that are scheduled AFTER the 500ms may have run as well. To fix this, we can use the freezeTime feature from hoot. It simply give the full control to hoot, and do not call the real setTimeout function. 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
Purchase reports now calculate product volume correctly when orders use pack-based units of measure. This ensures reporting reflects the real total volume purchased, improving accuracy for purchasing and inventory analysis.
Original PR description
_______________________________________ ## Short functional explanation of the error When setting the unit of measure as packs, the volume of products aren't computed correctly. ## Reproduction Steps…
_______________________________________ ## Short functional explanation of the error When setting the unit of measure as packs, the volume of products aren't computed correctly. ## Reproduction Steps 1. Go to settings. In the purchase section, click on Units of Measure & Packagings. 2. Click on new, set the unit name as "pack of 4", and set the quantity of the reference unit at 4. Set the reference unit as "units." 3. Go to products and create a test product. 4. In the inventory tab, set the volume greater than 0. 5. Go back to purchase and click on new. Add a line containing the test product, a set quantity, and set as unit "pack of 4." 6. Confirm the order, click on receive then validate. 7. Click on the reporting tab, then purchase. Set the measure as volume and click on the bar chart button. Then, click on the blue column and click on the row corresponding to the purchase operation. ### Expected behavior Let's say we set the product volume as 4 m³, and we purchased one pack of 4. The total volume would be (product volume) * (number of products), which would correspond to 4*4 = 16. ### Unexpected behavior Instead of 16, the total volume shows 1. ## Origin of the issue In the code, the volume is obtained with the operation (product volume) / (number of products) _________________________________________ opw-4871100 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#215605
Invoices created from Point of Sale orders now include the order name in the Customer Reference field. This makes it easier for staff to match backend invoices with the original POS transaction and reduces manual lookup work.
Original PR description
## Short functional explanation of the error When selling items in the point of sale module with an invoice, when we check said invoice in the backend, the customer reference field is empty. ##…
## Short functional explanation of the error When selling items in the point of sale module with an invoice, when we check said invoice in the backend, the customer reference field is empty. ## Reproduction Steps 1. Go to Point of sale and open a shop interface. Add a random item to the basket and select a customer. 2. Click on payment, then check Invoice, select a payment method, and Validate. 3. Click on the hamburger menu on the top right and click on Backend. 4. Hover the box of the shop you opened with your mouse. In the top right corner of the box should appear a 3-dot menu. Click on it and click on Sessions. 5. Click on the latest session ID. On the top of the page, click on the "Orders" smart button. 6. Click on the order you just finalized. On the top of the page click on the "Invoice" smart button. 7. Click on "Other info" tab. ### Expected behavior The Customer Reference field should be filled with the name of the order. ### Unexpected behavior The Customer Reference field is left empty. ## Origin of the issue When setting the values for the invoice, the field 'Ref' was absent. opw-4732492 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218158
This update makes an automated live chat test more reliable by removing an unnecessary step that could randomly fail. It helps ensure browser back-and-forth navigation between live chat sessions and discussions is consistently validated without affecting day-to-day user behavior.
Original PR description
The `test_session_history_navigation_back_and_forth` test sometimes fail. The test ensures we can navigate between the session list view and discuss using the browser history. To do so, the tour first accesses the list view using the command palette. However, command palette sometimes doesn't open. The command palette part of the tour is useless as the view can directly be accessed by passing the correct url to the `start_tour` function. This commit removes the command palette part of the tour thus fixing the issue. fixes runbot-108129 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#220539 Forward-Port-Of: odoo/odoo#220345
Sales orders imported into Point of Sale now keep the tax position set on the original order, even when it differs from the customer's default. This helps ensure accurate taxes and pricing at checkout when fulfilling sales orders through PoS.
Original PR description
When a sales order is imported into the PoS, the tax position does not match if the sales order has a different tax position than the one assigned to the partner. This commit ensures that the tax position will always be the one assigned to the sales order and not that of the partner. taskId: 4963118 Forward-Port-Of: odoo/odoo#220709 Forward-Port-Of: odoo/odoo#219869
The point of sale now handles cases where a register session was deleted from another device while a user is still on the opening screen. Instead of showing an error, the screen refreshes so staff can continue working without disruption.
Original PR description
Steps to reproduce: 1. Open a POS session on two devices. Leave both on the opening control screen. 2. On Device 1: - Click Open the Register. - Then click Close the Register. - Click on Backend ( the session is deleted) 3. On Device 2: - Click Open the Register. - This will result in a MissingError. After this commit, the case where the session has been deleted is handled, and the UI is refreshed to ensure the user can continue working without displaying the exception. Retarget of https://github.com/odoo/odoo/pull/218381 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220310
Reception report PDFs with many products now print cleanly across multiple pages. The change prevents product rows from overlapping with section headers, making large reception reports easier to read and use.
Original PR description
## Short functional explanation of the error When printing a reception report containing a lot of products, the top row of the pages after the first one is overlapped with its corresponding header in…
## Short functional explanation of the error When printing a reception report containing a lot of products, the top row of the pages after the first one is overlapped with its corresponding header in the resulting PDF. ## Reproduction Steps 1. Open the settings. In the inventory section, enable "Reception Report". 2. Create a new quotation and add at least 40 different products. Each product should have at least 1 copy in stock, and the quantity to order must be greater than the quantity we have of this product in stock. 3. Confirm the sales order. 4. Create a new purchase order and add the exact same products you added in the quotation. 5. Confirm the order and click on the "Recept" smart button. 6. Click on the "Allocation" smart button and click on the "Assign all" gray button. 7. Click on print and open the PDF once it finishes downloading. ### Expected behavior Each row (corresponding to the reception of a product) and its corresponding header is printed properly, regardless of how many pages constitute the report. ### Unexpected behavior The PDF has more than one page, and on the top of the second page, the product row is overlapped with the header of its corresponding section. ## Origin of the issue It comes from an issue with WKHtmltopdf itself: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1524 The report uses the "thead" tag for the headers. However, in some cases, when the header is linked to a table dynamically (with for-each, for example), WebKit ignores or breaks the "Thead" behavior. ## Explanation of the fix I override the default behavior of thead, which repeats the header automatically at each new page, with a new style. Now, the "Thead" special behavior is ignored and treated like ordinary lines. The header isn't shown at each new page anymore, avoiding the overlapping of product rows. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#215398
The keyboard shortcut shown while switching views now stays visible instead of overlapping the active view button. This makes the view switcher clearer and easier to use for users who rely on shortcuts.
Original PR description
Previously when switching views using the hotkey, the hotkey (SHIFT + V) was not properly visible, it was overlapping with the active view button. After this commit the hotkey (SHIFT + V) will be visible and not overlap with the active view. task-4828401 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217639
Fixes an error that could stop users from sending multiple invoices at once when the invoice email template used custom recipients. This helps accounting teams complete batch invoice sending reliably without manual workarounds.
Original PR description
Currently, an error occurs when sending invoices in bulk. Steps to Reproduce: - Install the `account` module. - Go to `Email Templates` and open `Invoice: Sending`. - In the `Email Configuration`,…
Currently, an error occurs when sending invoices in bulk. Steps to Reproduce: - Install the `account` module. - Go to `Email Templates` and open `Invoice: Sending`. - In the `Email Configuration`, uncheck `Default Recipients` and enter `demo@gmail.com` in the `cc` field. - Go to `Invoices`. - Select multiple invoices and click `Send`. `KeyError: <NewId origin=33>` This error occurs when sending invoices in bulk. As mentioned in commit https://github.com/odoo/odoo/commit/058d324855a6e2fe3df51386aa153d46419766bf, the issue was introduced in commit https://github.com/odoo/odoo/commit/39d1907d77ca9c88431e7e9dc9e8c938c79a2987, where the _compute_alerts method attempts to set an alert in the wizard. However,since this is a computed field, the wizard record has a NewId and calls the method with a transient record [1]. When trying to access record.id, it returns a NewId [2], and later, when this NewId is used as a res_id [3],it raises a KeyError. [1]-https://github.com/odoo/odoo/blob/aff5f006d5b1996ea3ecc67998067cd0e292cf2a/addons/account/wizard/account_move_send_batch_wizard.py#L63 [2]- https://github.com/odoo/odoo/blob/c70bca77d0447b005b3898e1861facc2828475fc/addons/mail/models/mail_thread.py#L2037 [3]- https://github.com/odoo/odoo/blob/c70bca77d0447b005b3898e1861facc2828475fc/addons/mail/models/mail_thread.py#L2084 This commit fixes the above issue by using move_ids._origin, ensuring that the method is always called with real records, and removes the changes from the previous commit https://github.com/odoo/odoo/commit/058d324855a6e2fe3df51386aa153d46419766bf. sentry-6562659542 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217730
This update allows list views to correctly use settings for creating, editing, and deleting groups. It prevents errors when those options are configured, improving reliability for affected views without changing user workflows.
Original PR description
Forgot to add the attributes `group_create`, `group_edit`, and `group_delete` in the list `rng`, which was causing an
error when they are used.
In this commit added attributes.
https://github.com/odoo/odoo/commit/0c18c0ee29458ed4724dc4337d9f6a060d09165f
https://github.com/odoo/odoo/commit/224d592ca3093b0a79c5866a3845ea171252d4b4
task-4489162The self-ordering page now hides product categories when they only contain special internal products that customers cannot order. This prevents restaurants from showing confusing empty categories, improving the ordering experience for guests.
Original PR description
Steps to reproduce: - Install the pos_black_box_be module. - Configure a Belgian restaurant and enable self-ordering. - Open the self-ordering page. - The category 'Fiscal category' is displayed even though it does not contain any products. This commit ensures that categories containing only special products (which are not displayed) will no longer appear on the self-ordering page. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220419 Forward-Port-Of: odoo/odoo#217642
Fixes an issue where an employee’s current work location could show as “unspecified” after changing today’s work location before saving. The presence tooltip now reflects the selected daily work location, reducing confusion for HR users and managers.
Original PR description
Step to reproduce:
------------------
* Go on Employees
* Click on one Employee
* Change a today worklocation "office" (don't save, you need to have the little cloud)
* Hover over hr presence icon
This title will be "unspecified" and not "office".
Reason:
--------
name_work_location_display is computed but doesn't depends of daily worklocation field (monday_worklocation, tuesday...)
Solution:
---------
Depends of these daily worklocation field
task-4948488
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#220359
Forward-Port-Of: odoo/odoo#219222This fix makes an automated check in the Sales Project area wait correctly before selecting a newly created sales order line. It reduces false test failures when the app is installed without demo data, helping keep releases more stable without changing user-facing behavior.
Original PR description
Steps to reproduce the issue: 1- install sale_project without demo data 2- as the test is not deterministic, adding step_delay may help reproducing it The test was failing because the tour was not waiting for the modal to close before trying to click on the created sale order line. so accoding to this line https://github.com/odoo/odoo/blob/18.0/addons/sale_project/models/sale_order_line.py#L63-L63 the New Sale order line have in it a default product which doesnt open a modal build_error-163102 Forward-Port-Of: odoo/odoo#220179
This fix prevents an error from appearing in the restaurant point of sale after a customer completes and pays for a mobile self-order. It improves reliability for restaurants using QR ordering with online payments and preparation printers.
Original PR description
**Configuration:** - Restaurant mode - Self-order mode: "QR + Ordering" - Pay after: "Each order" - Online payment is enabled for self-order **Steps:** - Open the restaurant UI in one tab. - Open the self-order UI in another tab. - Process a self-order with successful online payment. - Switch to the restaurant tab — a server traceback appears. **cause:** - The `notify_synchronisation` method attempted to read POS records with empty record IDs, causing the traceback. **Fix:** - Skip processing records with empty IDs before making server calls. Task-4858105 Forward-Port-Of: odoo/odoo#213500
This update makes an automated website builder test more reliable by ensuring time-based checks run consistently, even under heavy system load. It also removes unused website builder code, reducing maintenance overhead without changing user-facing behavior.
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
Website editors can no longer accidentally turn off a parallax effect by setting its intensity to zero. The zoom in and zoom out parallax options now behave as labeled, making page design controls more predictable.
Orders sent to preparation from a point-of-sale printer are now checked and synchronized so the same order is not printed multiple times across devices. This reduces duplicate kitchen or preparation tickets and helps staff avoid confusion when handling orders.
Original PR description
*: pos_urban_piper_enhancements Before this change, when a device sent an order in preparation via the ticket printer, this could result in the same order being printed by multiple devices, as the order was not synchronized after it was sent. The error is a bit tricky, because if the user had installed a preparation screen, the order was sent to the preparation screen via syncAllOrders. In this case, the order was correctly synchronized and the other devices were informed of the changes. This commit adds two things. - We check the server before sending the order to preparation to make sure it has not already been sent. - Even when the user does not have a preparation display, the order will be synchronized after being sent to a printer. Forward-Port-Of: odoo/enterprise#91093 Forward-Port-Of: odoo/enterprise#91006
Fixes an issue that prevented users from merging duplicate records in the Data Cleaning app after a recent system change. This restores the merge action so deduplication workflows can continue without an unexpected error.
Original PR description
Currently an error occurs when we try to merge data in deduplication. Steps to replicate: - Go to: Data Cleaning > Configuration > Deduplication. - Open any Deduplication Rules > Deduplicate > select…
Currently an error occurs when we try to merge data in deduplication. Steps to replicate: - Go to: Data Cleaning > Configuration > Deduplication. - Open any Deduplication Rules > Deduplicate > select any record (Make sure at least one record is available in list view). - Click `Merge` on top left. Error: `ValueError: invalid literal for int() with base 10: 'NaN'` The error because of a recent [refactor](https://github.com/odoo/odoo/pull/205486) where the data of a `many2one` will be an object rather than an array. (task-[3547961](https://www.odoo.com/odoo/project/49/tasks/3547961)) In `saas-18.3`, `record.data.group_id` (many2one field) was an array, so the line [1] worked perfectly. But starting in `saas-18.4`, after the change, the value became an object instead of an array. Because of that, `record.data.group_id[0]` is now `undefined`, and `parseInt()` returns NaN, which causes the `int()` on line [2] to throw a `ValueError`. [1] - https://github.com/odoo/enterprise/blob/7d020d73762a17386cae4b68c15a5d59a51fb480/data_cleaning/static/src/views/data_merge_list_view.js#L108 [2] - https://github.com/odoo/enterprise/blob/7d020d73762a17386cae4b68c15a5d59a51fb480/data_cleaning/models/data_merge_group.py#L113 The lines that returns object is [this](https://github.com/odoo/odoo/blob/564348a5172ea98b38c903686c21d007d0e57b48/addons/web/static/src/model/relational_model/utils.js#L517-L523). This commit solves the problem by accessing the ID using `.id` instead. sentry-6739344848
Commission calculations now account for subscription transfer logs during renewals, so sales teams receive credit based on the correct recurring plan rates. The update also prevents duplicate achievement lines when no currency is set and improves commission report performance for larger datasets.
Original PR description
PURPOSE In order to take into account the achievement rate based on recurring plan for MRR log on a renewal, we need to take into account transfer logs SPECIFICATIONS Take into account transfer logs…
PURPOSE
In order to take into account the achievement rate based on recurring plan for MRR log on a renewal, we need to take into account transfer logs
SPECIFICATIONS
Take into account transfer logs in achievements computation. Source should be clear that it's a transfer log of a renewal
Example:
If you have a Monthly sub to 100$/month but the yearly of 1000/year (MRR = 83.33) With a commission plan rewarding: 80% MRR of Monthly and 100% MRR of yearly
If you renew a montlhy into a yearly --> MRR that was 100 become 83,33 so you have a negative MRR so a negative commission and a negative on yearly so with more weight (100% instead of 80)
Current:
Renew in into yearly: 100% of MRR change -16.67 = -$16.67
New monthly 80% of MRR change $100 = $80
Total = 63.33 (modifié)
New
New monthly 80% of MRR change $100 = $80
Transfer 1 : 80% of MRR change -100 = -$80
Transfer 2 : 100% of MRR change +100 = +$100
Contraction of MRR: 100% of MRR change -16.67 = -$16.67
Total = 83.33
Moreover this PR:
- fix a bug when achievements were duplicated when no currency was set.
- improve performances by creating a temporary table for invoice rules.
taskid-4783929
Forward-Port-Of: odoo/enterprise#88646Uploading an attachment from the Documents chatter no longer shows an unnecessary progress card or row in the main kanban or list views. This keeps the Documents workspace visually cleaner and avoids confusing users with temporary upload items in the wrong place.
Original PR description
Step to reproduce: - In Documents, open the chatter either on a folder or a document. - Upload an attachment through the chatter. - You will see the upload kanban card / list row showing the progression. There should be no visual in kanban/list views showing the progression. Task-4863051 Forward-Port-Of: odoo/enterprise#90836 Forward-Port-Of: odoo/enterprise#87410
Disallowed expense reports no longer fail when entries have a 0% or missing rate. The report now keeps those lines uniquely identified, preventing duplicate key errors and improving reliability for affected accounting reports.
Original PR description
Before this **PR**: When only the account_disallowed_expenses module was installed, the report failed with a duplicate key error if a line had a 0 rate or no rate at all. This was because such child lines were assigned the same line_id as their parent. After this **PR**: Lines with a 0 or no rate have the parent account appended to their line_id to ensure uniqueness and avoid key collisions. Forward-Port-Of: odoo/enterprise#90236
Customer statement emails now handle selected contacts that do not have a name. This prevents scheduled report sending from failing when customer selections include unnamed contacts, improving reliability for accounting workflows.
Original PR description
**PROBLEM** In the accounting app, when selecting multiples customers, if one of them doesn't have a name, the cron sending the report will traceback. **STEP TO REPRODUCE** - On a clean db, install…
**PROBLEM** In the accounting app, when selecting multiples customers, if one of them doesn't have a name, the cron sending the report will traceback. **STEP TO REPRODUCE** - On a clean db, install the account_reports module - From the accounting app, create a new company customer (Customers/Customers) - From that new company customer form view, add a new contact of type "other" and don't specify a name for it. - Create an invoice for the company - From the customer list view, select all, and trigger the action "Open Customer Statements" - Send -> Print and Send - Check the console, the cron task should traceback on the template **CAUSE** In accout_report.py, we get the name of each selected partners, and we don't check if the name doesn't exist. In the template `pdf_export_filters`, we try to join all the name in a string, it fails because one of the name isn't a string (its value is False because it doesn't exist on the partner record). **FIX** When getting the partners names, filter out the partners without names. opw-4916660 Forward-Port-Of: odoo/enterprise#90154
Fixes an issue in Odoo Sign where radio button groups lost their mutual selection behavior when a template layout was reused on a new document. This preserves the intended signing experience and prevents recipients from selecting multiple options in what should be a single-choice group.
Original PR description
If applied, this commit will make so that when a user uses the layout of a template document on a new document, the radio buttons will stay linked.…
If applied, this commit will make so that when a user uses the layout of a template document on a new document, the radio buttons will stay linked. _____________________________________________________ Using the layout of a template document, containing radio buttons, on a new document will unlink radio buttons, making them useless. 1. Go to the Sign module, and click on the Templates tab. 2. Click on the "Upload PDF" purple button, and upload a PDF of your choice. 3. On the left side of the screen, there's a panel where we can drag and drop sign items. Drag and drop a Radio button. 2 buttons will automatically show, and a yellow link will appear between the buttons. This link indicates that, when a user opens the document to sign, when clicking on a radio button, the other one will automatically be unselected if previously selected. 4. Save and return to the Templates window. 5. A new row has appeared with the name of the document. On the right side of this row, hover the house next to the share button and click on the 3 dots. Then, click on Use Layout. 6. Upload a PDF of your choice. 7. When the PDF shows, there's no yellow link between the radio buttons, unlike on the template from which the layout was used. In the file sign/models/sign_document.py, in the method _copy_sign_items_to(self, new_document), we copy every sign item from the template to the new document. However, the copy method we call doesn't take into consideration the special link between radio buttons, replicating the buttons correctly but not the link. This link is expressed by the radio set to which the radio buttons belong: indeed, after the copy of sign items, each radio button belongs to a different radio set, separating them. ### Explanation of the fix The fix consists of a rework of the _copy_sign_items_to method and a brand-new method specifically used to copy radio buttons. To keep the link between them, we assign all the buttons of the same set on the original documents to the same brand new radio set. The first button is copied normally: this creates a new radio set. Then, for the remaining buttons, we call copy_radio_item, to which we pass the button created first to use the information the next buttons will share with it. ______________________________________________________________ opw-4842590 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#87536
Users can now clear date fields on existing commission plans without causing a save error. This prevents an unexpected crash and helps sales administrators update commission plan validity periods more reliably.
Original PR description
Currently, an error occurs when clear the date_to field from an already created record. Steps to Reproduce: - Install the `sale_commission` module. - Go to `Commission Plans` and create a record. -…
Currently, an error occurs when clear the date_to field from an already created record. Steps to Reproduce: - Install the `sale_commission` module. - Go to `Commission Plans` and create a record. - Now, clear the `date_from` field and save. `TypeError: '>' not supported between instances of 'bool' and 'datetime.date'` This error occurs when we clear the date_to field from an already created record. The error started occurring after https://github.com/odoo/enterprise/commit/926c8f041b51a04f0153be27cfcc8658a07be5b0 this commit that introduced the daterange widget for the date_from field. And when we clear the date_to field and try to save, it triggers the constraint [1] and raises the error. [1] https://github.com/odoo/enterprise/blob/377321fd7e7b1b2026734b75c79c74c8947e2e6c/sale_commission/model/commission_plan.py#L64 This commit ensures that the record is saved only if the date_to field is also present in the record. sentry-6710699656 Forward-Port-Of: odoo/enterprise#88769
36 changes
Resolved issues and error corrections
Corrects an issue where invoicing a closed point-of-sale order could fail when cash rounding was enabled only for cash payments and the customer used a mix of bank and cash payment. This helps businesses avoid blocked invoices and accounting imbalance errors in affected POS sessions.
Original PR description
Before this commit, an imbalance entry error occurred when invoicing a posted order under specific conditions. This issue arose when cash rounding was enabled only for the cash payment method, but the order was paid using both bank and cash. For example, if an order had a total of 12.91, and was partially paid with a bank transfer of 15.59, resulting in a cash return of -2.70, the session could be closed. However, attempting to invoice this order after closing the session would fail due to the imbalance. opw-4912399 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218430
Fixed an issue where customers who already had loyalty points could still claim a reward after the program's maximum usage limit had been reached in the current Point of Sale session. This helps ensure promotional limits are applied consistently and prevents unintended extra reward redemptions.
Original PR description
When an existing partner with points tries to claim a reward from a loyalty program that has reached its max usage in the current session, he was still able to claim the reward. Steps to reproduce: ------------------- * Create a loyalty program with max usage set to 1 * Create a partner and assign points to him * Open PoS and select any partner and make an order * Claim the reward from the loyalty program * Select the partner that already has points * Make an order and try to claim the reward again > Observation: The reward can be claimed, even though the max usage is already reached. Why the fix: ------------ When updating programs, we were not removing the couponPointChanges for programs that are not applicable anymore. We now make sure to delete them when the program is not applicable anymore. opw-4805704 Forward-Port-Of: odoo/odoo#220460 Forward-Port-Of: odoo/odoo#218425
The Calendar app’s “Attending?” filter now correctly shows events based on the current user’s attendance status, such as declined events. This fixes searches that previously returned no results, helping users find and manage relevant meetings more reliably.
Original PR description
The filter on an event's "Attending?" status was not working correctly. When filtering, the search would always return an empty result set because the underlying search implementation was logically flawed. It incorrectly compared calendar.event IDs with calendar.attendee data, which could never match. This commit corrects the `_search_current_attendee` method to properly query the `calendar.attendee` model. It now finds the intersection of attendees that both belong to the current user and match the filter criteria (e.g., state is 'declined'). It then uses these results to return the correct parent calendar events. A unit test has been added to verify the filter now works as expected. opw-4892386 Forward-Port-Of: odoo/odoo#218878
This change updates a point of sale test so it no longer depends on demo data being present. It helps ensure automated checks run consistently, reducing false failures during development and release validation.
Original PR description
Before this commit: = - The test `test_quantity_package_of_non_basic_unit` used `product_uom_inch`, which is `archived` by default, causing the test to fail without demo data. - It only worked with demo data because `l10n_us_account` `unarchives` this UoM. After this commit: = - Created a **test UoM** to ensure consistent test behavior. Runbot-error: 223122 Forward-Port-Of: odoo/odoo#214547
This fix lets Odoo hide or disable image transformation controls in contexts where they do not work, such as PDF reports. It prevents users from applying changes that would be ignored, reducing confusion and improving editing reliability.
Original PR description
Problem: In some contexts, such as reports, the `transform` option is not needed or applicable. For example, `transform` is not supported by `wkhtmltopdf`, so any applied transformation is ignored. Solution: Introduce the ability to disable the `transform` option when needed. opw-4809761 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220110 Forward-Port-Of: odoo/odoo#218352
Paid orders created through QR-code self-ordering now appear correctly in the POS ticket list. Staff will see the proper paid status and refund action, reducing confusion when handling already-paid customer orders.
Original PR description
**Steps:** - Configure POS with self-ordering via QR code and online payment. - Open a session and place a paid order through self-ordering. - In the POS UI, open the TicketScreen and apply the "Paid Orders" filter. **Issues:** - The paid order does not show the "Paid" tag. - The "Load Order" button appears instead of the "Refund" button. **Cause:** - The paid order retains an outdated uiState, with `uiState.locked` incorrectly set to false. **Fix:** - Use `finalized` instead of `uiState.locked` to determine order state on TicketScreen. - Remove the unused `locked` property from `uiState` in posOrder. Task: 4745869 Related: odoo/enterprise#86684 Forward-Port-Of: odoo/odoo#220193 Forward-Port-Of: odoo/odoo#207406
This update prepares Odoo for newer platform versions, including Python 3.13 and Debian Trixie, by adjusting dependencies and internal compatibility checks. It helps keep deployments reliable on upcoming operating system environments while also aligning tests with changed Python and library behavior.
Original PR description
Forward-Port-Of: odoo/odoo#220147 Forward-Port-Of: odoo/odoo#219270
This fix makes Odoo more accurately decide when users are allowed to publish website pages and partner-related content. It prevents misleading publish options from appearing when the user does not have the right access, reducing confusion and failed publishing attempts.
Original PR description
*: website_crm_partner_assign, website_customer, website_membership, website_partner Commit [1] (alongside commits [2] and [3]) introduced a new context key `can_publish_unsudo_main_object` with the…
*: website_crm_partner_assign, website_customer, website_membership, website_partner Commit [1] (alongside commits [2] and [3]) introduced a new context key `can_publish_unsudo_main_object` with the goal of properly computing `can_publish` without sudo... but it missed using it properly. The related test was passing... because it was also not properly written. This commit fixes the issue by using the context key at the proper places. However, this limits the fix to pages and partners at the moment as the bug is not critical in stable versions. It however fixes a test while run in no-demo (which becomes the norm in later versions). With that in mind, this also changes the view (by *adding* things to be as stable as possible) to go around the use of the context key and make new databases properly compute `can_publish` for all records type. Old databases will keep the old behavior for some models, which leads to displaying the "Publish" button but not be able to use it (access right warning). [1]: https://github.com/odoo/odoo/commit/d47d824fc484e1592fc4af8d0d378d5a4a579550 [2]: https://github.com/odoo/odoo/commit/1a83b2508b9383e2b7df192f8641751f71f852da [3]: https://github.com/odoo/odoo/commit/436a167dedb2ed008bcb88e8a4eccafc8d20812c Related to runbot-161791 Forward-Port-Of: odoo/odoo#220292 Forward-Port-Of: odoo/odoo#219389
Vendor bills created before goods are received now calculate foreign-currency amounts using the full billed quantity, not just one unit. This also prevents small unwanted exchange differences when the related receipt is later validated, improving accounting accuracy for purchase workflows.
Original PR description
**Current behavior:** Creating a purchase order in a foreign currency and billing the product prior to reception will produce 2 issues: A) The bill line for the product will only make a conversion of…
**Current behavior:** Creating a purchase order in a foreign currency and billing the product prior to reception will produce 2 issues: A) The bill line for the product will only make a conversion of 1 single unit of the product with the defined currency exchange rate, making the amount on the line incorrect when qty > 1 B) When the receipt is finally validated, there will be an unwanted exchange difference on the journal items generated due to asymmetrical rounding for the bill AMLs and receipt valuation AMLs **Expected behavior:** Correct bill line currency amounts and symmetric rounding. **Steps to reproduce:** 1. Set the company currenct to IQD, make a product invoiced on ordered qty, for sake of example set cost to 500 IQD 2. Create a currency exchange record to USD with a company rate of `0.00756` 3. Create a PO for 13 of the product created in step 1, with a discount of 1% 4. Confirm the PO and create the bill -> post it * Issue A) look at invoice line, see only 1 unit in the converted currency amount is accounted for by the `balance` 5) Receive the product -> look at the journal items generated and see that there is a diff of 0.185 IQD **Cause of the issue:** A) commit: 90158f6 added a method to try and calculate an AML balance from its purchase line values, but mistakenly is using `qty_received` instead of `qty_to_invoice` which explains why this issue only presents for the bill-before-receipt flow B) commit: 9f046d5 is using `round=False` context for `AccountTax.compute_all()` when the expected key is `round_base` **Fix:** A) Replace `qty_received or 1` with `qty_to_invoice` * Also make the test added in 90158f6 more robust B) Add `round_base=False` alongside the `round` key (not removing as that existing one could have become expected in this context) opw-4689170 Forward-Port-Of: odoo/odoo#216898 Forward-Port-Of: odoo/odoo#205850
This fixes two editor issues that could disrupt content editing: pasted list items now keep the correct structure, and bold or italic formatting can be removed even when selected text includes line breaks. The change makes website and HTML editing more reliable for users working with copied content and multi-paragraph selections.
Original PR description
**Current behavior before PR:** **Issue 1:** - Paste a content with multiple `<li>` elements without `ol/ul` tag, each `<li>` having a paragraph element inside. - Try to create a list from these…
**Current behavior before PR:** **Issue 1:** - Paste a content with multiple `<li>` elements without `ol/ul` tag, each `<li>` having a paragraph element inside. - Try to create a list from these elements. - List is created with wrong element structure. The problem occurs because when pasting multiple `<li>` elements without an `<ol>/<ul>` tag, `sanitizeNode` replaces existing `<li>` elements with new `<p>` elements. Since each `<li>` already contains a `<p>`, this results in paragraphs being nested inside other paragraphs. As a result, creating the list from these paragraphs leads to an incorrect structure. **Issue 2:** If there are multiple paragraph selected along with newline character nodes `(\n)`, it is not possible to remove bold or italic format from selected content using toolbar. The issue happens because `isSelectionFormat` method fails to give correct value if traversed nodes contains one or more newline `(\n)` characters. **Desired behavior after PR is merged:** **Issue 1:** Now, if an `<li>` contains a `<p>`, the `<li>` is unwrapped instead of creating a new paragraph, resulting in a correct element structure when creating a list. **Issue 2:** Now, `\n` nodes are filtered from traversed nodes so that format can be removed from selected content. task-4752385 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217361 Forward-Port-Of: odoo/odoo#208127
This fix prevents valid product combinations from being incorrectly blocked in Point of Sale after an attribute line is removed from a product. It helps ensure staff and customers can continue selling available variants without disruption in POS and self-order flows.
Original PR description
Before this commit, removing an attribute line from a product would inadvertently prevent the sale of any combination in the PoS interface. opw-4947529 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219251
Reception report PDFs with many products now print cleanly across multiple pages. This prevents product rows from overlapping with section headers, making longer warehouse reception reports easier to read and use.
Original PR description
## Short functional explanation of the error When printing a reception report containing a lot of products, the top row of the pages after the first one is overlapped with its corresponding header in…
## Short functional explanation of the error When printing a reception report containing a lot of products, the top row of the pages after the first one is overlapped with its corresponding header in the resulting PDF. ## Reproduction Steps 1. Open the settings. In the inventory section, enable "Reception Report". 2. Create a new quotation and add at least 40 different products. Each product should have at least 1 copy in stock, and the quantity to order must be greater than the quantity we have of this product in stock. 3. Confirm the sales order. 4. Create a new purchase order and add the exact same products you added in the quotation. 5. Confirm the order and click on the "Recept" smart button. 6. Click on the "Allocation" smart button and click on the "Assign all" gray button. 7. Click on print and open the PDF once it finishes downloading. ### Expected behavior Each row (corresponding to the reception of a product) and its corresponding header is printed properly, regardless of how many pages constitute the report. ### Unexpected behavior The PDF has more than one page, and on the top of the second page, the product row is overlapped with the header of its corresponding section. ## Origin of the issue It comes from an issue with WKHtmltopdf itself: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1524 The report uses the "thead" tag for the headers. However, in some cases, when the header is linked to a table dynamically (with for-each, for example), WebKit ignores or breaks the "Thead" behavior. ## Explanation of the fix I override the default behavior of thead, which repeats the header automatically at each new page, with a new style. Now, the "Thead" special behavior is ignored and treated like ordinary lines. The header isn't shown at each new page anymore, avoiding the overlapping of product rows. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#215398
This fix keeps the website editor toolbar from adding unwanted blank space below the page footer when it is hidden. It improves page layout consistency for users editing website content without changing visible functionality.
Original PR description
Description of the issue/feature this PR addresses: - Commit [189a7c96](https://github.com/odoo/odoo/commit/189a7c96e6e26825dc05c0c6466576fe63aa091e#diff-de0d67e89972b45b101a9c4b04f316824314b0d69aba6208528586f1edb4f01cL25-L40) moved scrollbar from `#wrapwrap` element to `<body>`, caused the space below the footer visible for the floating toolbar. Current behavior before PR: - Space below the footer was always visible, even when the toolbar was hidden. Desired behavior after PR is merged: - `top: 0;` is applied on `.oe-toolbar` to ensure it stays out of the layout flow. - This prevents unnecessary layout space and ensures correct toolbar positioning. task-4652202 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217270
This change removes an unnecessary database index for project collaborators because an existing uniqueness rule already supports the same lookup. It simplifies database maintenance without changing how users work with projects.
Original PR description
There is a unique constraint `_unique_collaborator`, whos first key is `project_id`, which will cover the necessity for an explicit index on `project_id` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale invoices now automatically include the related order name in the Customer Reference field. This makes backend invoice records easier to identify and reconcile after invoiced POS sales.
Original PR description
## Short functional explanation of the error When selling items in the point of sale module with an invoice, when we check said invoice in the backend, the customer reference field is empty. ##…
## Short functional explanation of the error When selling items in the point of sale module with an invoice, when we check said invoice in the backend, the customer reference field is empty. ## Reproduction Steps 1. Go to Point of sale and open a shop interface. Add a random item to the basket and select a customer. 2. Click on payment, then check Invoice, select a payment method, and Validate. 3. Click on the hamburger menu on the top right and click on Backend. 4. Hover the box of the shop you opened with your mouse. In the top right corner of the box should appear a 3-dot menu. Click on it and click on Sessions. 5. Click on the latest session ID. On the top of the page, click on the "Orders" smart button. 6. Click on the order you just finalized. On the top of the page click on the "Invoice" smart button. 7. Click on "Other info" tab. ### Expected behavior The Customer Reference field should be filled with the name of the order. ### Unexpected behavior The Customer Reference field is left empty. ## Origin of the issue When setting the values for the invoice, the field 'Ref' was absent. opw-4732492 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218158
This fixes an error that could appear when moving the final item from one table of contents block into another on a website page. Website editors can now reorganize these blocks without interruptions or crashes.
Original PR description
Since [1], a traceback appears when we drag the last block of a table of content into another one. Drag and drop two tables of content on the website page One by one, drag and drop the blocks from the second table to the first one traceback for the last one... This commit resolves the issue [1]:https://github.com/odoo/odoo/commit/6cd9606e285741b59042b9674bf6682273c43a69 task-4144022 Forward-Port-Of: odoo/odoo#180039
Fixes an issue where the drag-and-drop upload area stayed visible after users added documents to Expenses. After an upload or drop, users are returned to the expense list so they can see the generated expenses, even if OCR processing fails.
Original PR description
When dropping documents on Expense, the drop zones would stay being displayed. We now stop to display it when a file is uploaded / dropped. task-4942503 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Reordering rules now respect the replenishment unit of measure, so purchase orders and related warehouse transfers match how vendors actually sell products. This also improves quantity rounding for packaged goods and prevents manufacturing orders from being updated with quantities in the wrong unit.
Original PR description
**PROBLEM** 1. When setting up a product with vendor that sell the product in different packaging, when triggering the reorder, the PO use the stock UoM instead of the replenishement UoM. 2. Once the…
**PROBLEM** 1. When setting up a product with vendor that sell the product in different packaging, when triggering the reorder, the PO use the stock UoM instead of the replenishement UoM. 2. Once the first issue is fixed, we can notice the packaging quantity in the picking order is not exactly what it should be (rounding error of 0.01). 3. Once the first issue is fixed, there is a failing test concerning the manufacture procurement route. **STEP TO REPRODUCE** 1. activate the UoM and packaging option. 2. create a product with a vendor that sells it in a packaging. 3. create a reordering rule with the replenishement UoM being the packaging unit. 4. trigger the reordering, notice the PO doesn't use the right unit and the picking doesn't use the right packaging. (Same steps to reproduce, just revert my change on stock_move.py before) (To reproduce the 3rd issue, run the test in odoo/addons/sale_mrp/tests/test_sale_mrp_procurement.py) **CAUSE** The procurement for the reordering rule is always created with the stock UoM. The `_compute_packaging_uom_qty` method doesn't specify the rounding_method to use when converting from the product uom to the replenishment uom. By default, it uses the 'UP' method. The _run_manufacture method has a bug: when there is a new procurement for a product that has already a mo opened, it will try to update the mo quantity. To do so, it calculate a new quantity, by adding the previous quantity and the procurement quantity, but it assumes the quantity is in the product default uom which is not always the case (for example, when there is a replenishment UoM set on the reordering rule). **FIX** 1. If a remplenishement uom exists on the reordering rule, we create the replenishement with this unit instead of the stock one. 2. Use the 'HALF-UP' rounding method, to reduce the rounding error. 3. Converting the procurement quantity into the product default UoM before computing the new mo quantity. opw-4858992
The bank reconciliation widget now only suggests statement lines that are still waiting in the suspense account. This prevents already assigned bank statement lines from reappearing as possible invoice matches, reducing confusion and avoiding duplicate reconciliation work.
Original PR description
Create a bank statement line with partner A Assign it to a random account Create an invoice with partner A Confirm it. => The statement line appears It should not, it has been assigned. Only lines that are still on the suspense account should be taken into account --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The view-switching shortcut label now stays clearly visible when users change views with Shift + V. This prevents the shortcut hint from overlapping the active view button, making the interface easier to understand and use.
Original PR description
Previously when switching views using the hotkey, the hotkey (SHIFT + V) was not properly visible, it was overlapping with the active view button. After this commit the hotkey (SHIFT + V) will be visible and not overlap with the active view. task-4828401 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217639
When a salesperson changes the product on a quotation line after manually editing its price, Odoo now recalculates the price for the newly selected product. This prevents quotes from accidentally keeping the old product’s price, improving pricing accuracy for sales orders.
Original PR description
step to reproduce - Create a quotation, - Select a product - Update the price manually - change the product - The amount stays the same expectation: with change of product in SO, price should also recompute issue: currently,`_compute_price_unit` depends on `technical_price_unit` such that `price_unit` won't update if `price_unit` and `technical_price_unit` are not same. which is the case when price_unit was manually set, regardless of the product https://github.com/odoo/odoo/blob/12ef230df58122fbdac0b4c1b4781c535b8516ba/addons/sale/models/sale_order_line.py#L567-L570 we should reset to original price with change of product opw-4813069 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218192 Forward-Port-Of: odoo/odoo#213912
Fixes an error that could block users from sending multiple invoices at once when the invoice email template had custom recipients configured. This helps accounting teams send invoices in bulk reliably without manual workarounds.
Original PR description
Currently, an error occurs when sending invoices in bulk. Steps to Reproduce: - Install the `account` module. - Go to `Email Templates` and open `Invoice: Sending`. - In the `Email Configuration`,…
Currently, an error occurs when sending invoices in bulk. Steps to Reproduce: - Install the `account` module. - Go to `Email Templates` and open `Invoice: Sending`. - In the `Email Configuration`, uncheck `Default Recipients` and enter `demo@gmail.com` in the `cc` field. - Go to `Invoices`. - Select multiple invoices and click `Send`. `KeyError: <NewId origin=33>` This error occurs when sending invoices in bulk. As mentioned in commit https://github.com/odoo/odoo/commit/058d324855a6e2fe3df51386aa153d46419766bf, the issue was introduced in commit https://github.com/odoo/odoo/commit/39d1907d77ca9c88431e7e9dc9e8c938c79a2987, where the _compute_alerts method attempts to set an alert in the wizard. However,since this is a computed field, the wizard record has a NewId and calls the method with a transient record [1]. When trying to access record.id, it returns a NewId [2], and later, when this NewId is used as a res_id [3],it raises a KeyError. [1]-https://github.com/odoo/odoo/blob/aff5f006d5b1996ea3ecc67998067cd0e292cf2a/addons/account/wizard/account_move_send_batch_wizard.py#L63 [2]- https://github.com/odoo/odoo/blob/c70bca77d0447b005b3898e1861facc2828475fc/addons/mail/models/mail_thread.py#L2037 [3]- https://github.com/odoo/odoo/blob/c70bca77d0447b005b3898e1861facc2828475fc/addons/mail/models/mail_thread.py#L2084 This commit fixes the above issue by using move_ids._origin, ensuring that the method is always called with real records, and removes the changes from the previous commit https://github.com/odoo/odoo/commit/058d324855a6e2fe3df51386aa153d46419766bf. sentry-6562659542 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217730
Saving a spreadsheet global filter with a duplicate label and a selected value range no longer causes a crash. Users now see the duplicate label error directly, making the validation smoother and avoiding disruptive tracebacks.
Original PR description
Steps to reproduce: - Create a global filter with label 'aa' - Create a new text filter with the same label - Check 'Restrict values to a range' - Select a range with some values - Confirm the range selection - Click the save button Current behavior before PR: - A traceback occurred when saving the new filter with a duplicate label and a selected range. After the crash, the duplicate label error was shown. Desired behavior after PR is merged: - The duplicate label error is raised directly without triggering a traceback. Task: [4813177](https://www.odoo.com/odoo/2328/tasks/4813177)
Installing Accounting Reports or Accountant after Accounting now creates the VAT return journal when needed, even if the chart of accounts was already set up. This helps prevent missing VAT closing records and makes tax return setup more reliable for companies and branches.
Original PR description
Issue: The VAT return journal is not created when installing `account_reports` (or `accountant`) after `account`, when the CoA is already created. Solution: Create it in the post init hook. Note that…
Issue: The VAT return journal is not created when installing `account_reports` (or `accountant`) after `account`, when the CoA is already created. Solution: Create it in the post init hook. Note that we force the creation of the journal only when `accountant` is installed because it would make noise for invoicing only in most cases. It will still be created automatically when needed. Also, make the code a little bit more robust: * instead of mixing "default misc journal" and vat return journal logic, just use one logic * the function `_get_tax_closing_journal` could return multiple journals but was always used as if it could only contain one * the function `_get_tax_closing_journal` could not return any journal. Instead, we now create the journal or look for a value on the parent companies if any. * Manage `show_on_dashboard` in `create` also by using an inverse field. Even if in normal cases the journal will always be created after the company the thus set through `write`, it is not impossible to set it in `create` when creating company branches. Since it is always done when setting the journal on the company, there is no need to set the field in the post-init hook.
Studio now hides image transformation options when editing reports because those effects do not appear in generated PDFs. This prevents users from applying formatting that would be lost in the final PDF, making report previews and output more predictable.
Original PR description
Problem: Image transformations are not applied in generated PDFs because they are not supported by `wkhtmltopdf`. Solution: Disable image transform options when rendering reports to ensure expected output and avoid unsupported behavior. Steps to reproduce: - Open any report in Studio - Add an image - Apply a scale transformation - Generate a PDF preview > The image transform is not applied in the generated PDF opw-4809761 Forward-Port-Of: odoo/enterprise#90776 Forward-Port-Of: odoo/enterprise#89952
Fixes accounting reconciliation so models using a different currency calculate foreign currency amounts and balances correctly. It also prevents automatic reconciliation models from being created when users apply receivable or payable actions, reducing unintended accounting setup changes.
Original PR description
Before this commit when applying a reco model with a different currency, the amount currency and the balance were equals. task-4931177 Before this commit when applying the receivable or payable button, the automatic reco models would be created. We don't want that behavior task-4930730
This update keeps several Odoo Enterprise apps working reliably with newer Python 3.13 and Debian Trixie environments. It adjusts automated tests to handle date comparisons, translated date spacing, and PDF warnings more consistently, reducing upgrade-related failures without changing business features.
Original PR description
Forward-Port-Of: odoo/enterprise#90794 Forward-Port-Of: odoo/enterprise#90352
Clearing a document selection from the control panel now also clears the details panel. This prevents users from seeing stale document information after they have removed the current selection.
Original PR description
The details panel does not update when clearing the selection through the control panel. Steps to Reproduce: ==================== - Open the detailsPanel. - Select a document. - Click on a blank space, which removes the current selection. - Re-select a document. - Click the ‘x’ button on the control panel to clear the selection. - The document selection in the detailsPanel does not get cleared. Technical =========== In DocumentsRightPanel and how DocumentsDetailsPanel is handled, The panel relies on the `state.focusedRecord` to determine which record's details to display. However, when clicking the ‘X’ button in the control panel to clear the selection, the `state.focusedRecord` is not being Updated or cleared, the detail panel still shows the previously focused record. After this PR: Clicking the ‘x’ will properly clear the selection from the detailsPanel. Task-4752944
Uploading an attachment from the chatter in Documents no longer shows temporary upload progress cards or rows in the main kanban or list views. This keeps the workspace cleaner and avoids confusing users with duplicate or unexpected visual elements during uploads.
Original PR description
Step to reproduce: - In Documents, open the chatter either on a folder or a document. - Upload an attachment through the chatter. - You will see the upload kanban card / list row showing the progression. There should be no visual in kanban/list views showing the progression. Task-4863051 Forward-Port-Of: odoo/enterprise#90836 Forward-Port-Of: odoo/enterprise#87410
Mobile self-ordering orders are now sent to the preparation display as soon as the customer proceeds to pay, instead of waiting until cashier payment. This helps staff start preparing mobile orders earlier and avoids delays or missed visibility in the kitchen workflow.
Original PR description
When doing a self order from a mobile device, the order was not sent to the preparation display until it was paid at the cashier. Steps to reproduce: ------------------- * Setup a PoS with self-ordering mode set to 'mobile'. * Setup a preparation display to show orders from this PoS. * Place an order from a mobile device. * Click on "Pay" > Observation: The order does not appear on the preparation display. Why the fix: ------------ Instead of just sending the order from the kiosk, we also need to send it from the mobile device. opw-4819732 Forward-Port-Of: odoo/enterprise#90169
Fixes an issue where receiving a file reply in WhatsApp could trigger an error when request debugging was enabled. The system now logs file response size instead of trying to store binary content as text, improving reliability for businesses using WhatsApp messaging.
Original PR description
When Debug requests is enable on the whatsapp business account and user replies with the file, a traceback will appear. Steps to reproduce the error: - Install ``whatsapp`` and ``contacts`` - Create…
When Debug requests is enable on the whatsapp business account and user replies with the file, a traceback will appear. Steps to reproduce the error: - Install ``whatsapp`` and ``contacts`` - Create a whatsapp business account > Enable Debug requests - Create a contact > Add a phone number > send whatsapp message with any whatsapp template - Now reply with the file(ex. pdf or image) in message from the contact's whatsapp. - Traceback in terminal Traceback: ``ValueError: A string literal cannot contain NUL (0x00) characters.`` https://github.com/odoo/enterprise/blob/b52a93da7d680b60646cb08a9126cf6c12f5307d/whatsapp/models/whatsapp_account.py#L166 Here, ``message`` contains NUL (0x00) characters because user replies with the file, value for the ``message`` comes from the below response. response: https://github.com/odoo/enterprise/blob/b52a93da7d680b60646cb08a9126cf6c12f5307d/whatsapp/tools/whatsapp_api.py#L49-L57 Here, ``res.text`` contains NUL (0x00) characters. So, it will lead to the above traceback. sentry-6314521165 Forward-Port-Of: odoo/enterprise#83274
Fixed an issue where sending customer statements could fail if one of the selected customer contacts had no name. The system now skips unnamed contacts when preparing the report details, helping scheduled statement emails complete reliably.
Original PR description
**PROBLEM** In the accounting app, when selecting multiples customers, if one of them doesn't have a name, the cron sending the report will traceback. **STEP TO REPRODUCE** - On a clean db, install…
**PROBLEM** In the accounting app, when selecting multiples customers, if one of them doesn't have a name, the cron sending the report will traceback. **STEP TO REPRODUCE** - On a clean db, install the account_reports module - From the accounting app, create a new company customer (Customers/Customers) - From that new company customer form view, add a new contact of type "other" and don't specify a name for it. - Create an invoice for the company - From the customer list view, select all, and trigger the action "Open Customer Statements" - Send -> Print and Send - Check the console, the cron task should traceback on the template **CAUSE** In accout_report.py, we get the name of each selected partners, and we don't check if the name doesn't exist. In the template `pdf_export_filters`, we try to join all the name in a string, it fails because one of the name isn't a string (its value is False because it doesn't exist on the partner record). **FIX** When getting the partners names, filter out the partners without names. opw-4916660 Forward-Port-Of: odoo/enterprise#90154
The UrbanPiper point of sale integration now uses the actual finalized order status instead of an unused internal flag. This helps ensure order state is shown consistently on the ticket screen and removes obsolete internal data.
Original PR description
In this commit: ==== - Use `finalized` instead of `uiState.locked` to determine order state on TicketScreen. - Remove the unused `locked` property from `uiState` in posOrder. Task-4745869 Related: odoo/odoo#207406 Forward-Port-Of: odoo/enterprise#90829 Forward-Port-Of: odoo/enterprise#86684
Online synchronization fields no longer disappear when provider data is not supplied by OdooFin. This keeps bank connection details accessible and corrects a related search filter, requiring a module update.
Original PR description
The fields on the online synchronization were invisible if no provider_data wass put on the synchro. But now, this info is not given anymore from Odoofin. So, we should not hide these fields based on provider_data. Also fixed a search domain. It will need an update of the module. Forward-Port-Of: odoo/enterprise#91027 Forward-Port-Of: odoo/enterprise#90785
This fix prevents the disallowed expenses report from failing when expense lines have a zero or missing rate. It ensures each report line is uniquely identified, avoiding duplicate entry errors and improving report reliability.
Original PR description
Before this **PR**: When only the account_disallowed_expenses module was installed, the report failed with a duplicate key error if a line had a 0 rate or no rate at all. This was because such child lines were assigned the same line_id as their parent. After this **PR**: Lines with a 0 or no rate have the parent account appended to their line_id to ensure uniqueness and avoid key collisions. Forward-Port-Of: odoo/enterprise#90236
Fixes an issue where users could encounter an error when removing an end date from an existing commission plan. This prevents unnecessary save failures and keeps commission plan management smoother for sales operations.
Original PR description
Currently, an error occurs when clear the date_to field from an already created record. Steps to Reproduce: - Install the `sale_commission` module. - Go to `Commission Plans` and create a record. -…
Currently, an error occurs when clear the date_to field from an already created record. Steps to Reproduce: - Install the `sale_commission` module. - Go to `Commission Plans` and create a record. - Now, clear the `date_from` field and save. `TypeError: '>' not supported between instances of 'bool' and 'datetime.date'` This error occurs when we clear the date_to field from an already created record. The error started occurring after https://github.com/odoo/enterprise/commit/926c8f041b51a04f0153be27cfcc8658a07be5b0 this commit that introduced the daterange widget for the date_from field. And when we clear the date_to field and try to save, it triggers the constraint [1] and raises the error. [1] https://github.com/odoo/enterprise/blob/377321fd7e7b1b2026734b75c79c74c8947e2e6c/sale_commission/model/commission_plan.py#L64 This commit ensures that the record is saved only if the date_to field is also present in the record. sentry-6710699656 Forward-Port-Of: odoo/enterprise#88769
17 changes
Resolved issues and error corrections
Point of Sale now correctly accepts multiple existing serial numbers for the same product when creating new serial numbers is disabled. This prevents valid sales from being blocked during checkout and helps staff process tracked inventory reliably.
Original PR description
**Steps to reproduce:** - Install `point_of_sale`. - Go to POS -> configuration -> settings - Search 'Operation type' -> open picking type -> Disable `Create new` - Create a storable product 'test'…
**Steps to reproduce:** - Install `point_of_sale`. - Go to POS -> configuration -> settings - Search 'Operation type' -> open picking type -> Disable `Create new` - Create a storable product 'test' with serial tracking. - Add on-hand quantity with serial numbers. - In POS, select the product and choose one SN, - Select it again and choose another SN. **Observation:** - The order line should have 2 quantities with a list of Serial numbers chosen by the user. For one quantity, it's working fine, but for multiple quantities, an issue occurs. **Issue:** - While confirming edit serial numbers popup for multiple quantities, it checks whether each selected SN is valid or not. - The condition is that the entered SN is in the existing available SNs option. But the already chosen SN is not in the existing SN option, - Also, creating a new SN is disabled, so it's considered an invalid input. https://github.com/odoo/odoo/blob/876b7337eb689e0682ab48e9e833f9f0dc6bb8d2/addons/point_of_sale/static/src/app/store/select_lot_popup/select_lot_popup.js#L190-L193 **Solution:** - Added a condition to allow SNs that are already selected (matched by name and ID) to be considered valid inputs. opw-4865902 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where mail thread access and existence information could be left out when a request was present but empty. Users and connected features now receive the expected thread access status consistently, reducing confusion and preventing missing information in mail-related workflows.
Original PR description
Even if the request is an empty array, access (and existence of thread) should be sent. How to reproduce: https://github.com/odoo/odoo/pull/220605
This fix moves the affected employee candidate test coverage into the recruitment area where the required candidate functionality is available. It helps prevent nightly build failures caused by tests running without the needed recruitment setup.
Original PR description
Problem: ======== - Nightly build hr.candidate is not installed Solution: ========= - Change test and tour inside hr_recruitment runbot-230304
This fix prevents an error when a website editor changes a button snippet into a regular link and then saves. The editor now correctly hides button-specific options once the item is no longer a button, reducing failed saves and improving content editing reliability.
Original PR description
Problem: Saving the button snippet after changing its type to a link throws an error because `snippet_key` is `undefined`. Cause: The button snippet editor should be disabled if the button is changed…
Problem: Saving the button snippet after changing its type to a link throws an error because `snippet_key` is `undefined`. Cause: The button snippet editor should be disabled if the button is changed to a link. However, `updateOptionsUIVisibility` is only triggered on click events. In this case, the element type changes through the editor itself, not by clicking, so the UI isn't updated accordingly. Solution: Trigger a `click` event on the link element programmatically to call `updateOptionsUIVisibility` and hide the button snippet editor when the element is no longer a button. Steps to reproduce: - Drop a button snippet - Click inside the button to edit - Notice the Button snippet editor appears - Change the type to "Link" instead of "Primary" - The Button snippet editor is still visible - Click the floppy disk icon (save) in the snippet editor -> A traceback occurs opw-4936796 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219660
Event registrations purchased and paid for through Point of Sale are now marked as Registered instead of Attended. This aligns PoS behavior with website purchases and avoids incorrectly recording customers as having already attended the event.
Original PR description
Before this commit, if we buy an event registration from PoS and pay for it, its state will be 'done', i.e. "Attended" [1]. While if we buy the registration from the website and pay for it, its state is 'open', i.e. "Registered" [2]. We want the state of the registration to be 'open' when we buy it. After this commit, we set the state of events bought from PoS to 'open' as well, matching the case where we buy them from the website. [1]: https://github.com/odoo/odoo/blob/c3ae4b29c51c7b0cff11aac5f4bf4aab5fad16c9/addons/pos_event_sale/models/event_registration.py#L14 [2]: https://github.com/odoo/odoo/blob/c3ae4b29c51c7b0cff11aac5f4bf4aab5fad16c9/addons/event_sale/models/event_registration.py#L40 opw-4920574
Fixed a typo in the Peru localization data where Huancayo was incorrectly written with an extra space. This helps ensure city names appear correctly in addresses, reports, and related business records.
Original PR description
The Huancayo has an extra space in the name. Instead of Huancayo it is written Hua ncayo in the csv file. opw-4947526 Forward-Port-Of: odoo/odoo#219888
Users who have permission to manage pricelists can now archive them even if they do not have access to loyalty programs. This removes an unnecessary access-rights blockage and keeps pricelist administration working as expected.
Original PR description
Finetuning of d20b6f6407f49f9bff8cf3677b2fe07cb3588298, if a user had access rights on the pricelist model but not on loyalty programs, he wouldn't be able to archive a given pricelist. Has already been fixed in the aforementionned commit forward-port, starting from 18.2. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220608
This fixes an issue where the mail discussion system could ignore records when there were no field values to return. Users and processes can now still detect that a record exists, improving reliability in cases where record presence matters.
Original PR description
Knowing the existence of a record can be desirable, even if no fields need to be returned. How to reproduce: https://github.com/odoo/odoo/pull/220605
Odoo now better recognizes older Microsoft Word, Excel, and PowerPoint files, and avoids renaming newer Excel files as ZIP files when their type is detected too generically. This prevents portal uploads in Documents from receiving incorrect file extensions and reduces confusing warnings for users.
Original PR description
## [FIX] core: python3-magic vs .doc/.xls/.ppt [python3-magic](https://packages.ubuntu.com/noble/python3-magic)/[python-magic](pypi.org/project/python-magic) (apt/pip) is a frontend for…
## [FIX] core: python3-magic vs .doc/.xls/.ppt [python3-magic](https://packages.ubuntu.com/noble/python3-magic)/[python-magic](pypi.org/project/python-magic) (apt/pip) is a frontend for [libmagic](https://manned.org/man/ubuntu-noble/magic) the library that can introspect files to determine their types. The Documents app makes heavy usage of our mimetypes utilities to scan and fix the extensions of files uploaded by portal users. Everytime a portal user uploads a `.doc`/`.xls`/`.ppt` file, python3-magic is gonna guess the mimetypes `application/x-ole-storage` or `application/CDFV2` which are the mimetypes of the generic file format that Microsoft Office was using until 2006. The problem is that there is no specific extension for those two mimetypes as Microsoft was using the same file format for many of its office applications. In this work we enrich python3-magic's detection with our own, which is able to tell different `application/x-ole-storage` and `application/CDFV2` files apart. **Please note**: Excel files are detected only when the entire file is present. Excel files uploaded via the Documents app are not detected because Documents only `guess_mimetype` on the first 1kiB of the document. We also added a condition to keep the .doc/.xls/.ppt extension in case the generic `application/x-ole-storage` or `application/CDFV2` mimetype is guessed. Before it was emitting a warning due to the unknown extension. ## [FIX] core: python3-magic vs new (2025) .xlsx files [python3-magic](https://packages.ubuntu.com/noble/python3-magic)/[python-magic](pypi.org/project/python-magic) (apt/pip) is a frontend for [libmagic](https://manned.org/man/ubuntu-noble/magic) the library that can introspect files to determine their types. The Documents app makes heavy usage of our mimetypes utilities to scan and fix the extensions of files uploaded by portal users. Sometypes when portal user uploads a `.xlsx` file, python3-magic fails to detect the Microsoft Excel 2007+ (OOXML) mimetype and instead guesses a generic `application/zip`. Technically this is not wrong, OOXML files (like Java JAR and Python Weels) are using the zip format. This is quite strange because python3-magic is able to work with `.xlsx` files. I'm guessing that Microsoft deployed a new version of Excel and that magic doesn't correctly guess the new (2025) `.xlsx` files. Using a hex editor, the old (from our unittests) and new (from a 2025 support ticket) seem similar: OOXML files, deflate compression, same files present. They are a bit different, in the old the `[Content_Types.xml]` file comes last, in the new it comes first. The zip headers are different too, the old uses zip Data Descriptors, the new doesn't. The problem is that the Documents app uses the guessed mimetype to "fix" the extension of the uploaded file. So the portal-user's `file.xlsx` gets wrongly rewritten to `file.zip`. We first used an approach similar to the previous commit[^1], to use our own detection of OOXML files. It works great in base where we run the detection on whole files. However it doesn't work for the Documents app because it attempts to guess the mimetype only reading the first 1kiB of the uploaded file. A first PR odoo#213647 suggested to change Documents to load the whole file first, and then run `guess_mimetype`, but was rejected. In this work, we made so we don't fix the extension of zip-like files should the guessed mimetype be application/zip. [^1]: [FIX] core: python3-magic vs .doc/.xls/.ppt opw-4607156 opw-4753670
Point of Sale session closing messages now show cash differences with the correct number of currency decimal places. This avoids confusing long decimal values in the session chatter and makes cash reconciliation clearer for store staff.
Original PR description
**Issue:** When closing a PoS session with negative balances, the closing difference is displayed in the chatter box with an excessive number of decimal digits. **Steps to Reproduce:** 1. Install the…
**Issue:** When closing a PoS session with negative balances, the closing difference is displayed in the chatter box with an excessive number of decimal digits. **Steps to Reproduce:** 1. Install the Point of Sale app. 2. Navigate to Point of Sale > Open a new session. 3. Set the Opening Cash to 496.45. 4. Add a product priced at 65.86 to an order. 5. Confirm the payment via Payment > Cash > Validate. 6. Close the session and set Counted Cash to 560.40. 7. Navigate to Orders > Sessions. 8. Open the last closed session. 9. Observe that the closing difference is displayed with more than two decimal digits. Expected Behavior: The closing difference should be rounded to two decimal places for clarity. Actual Behavior: The closing difference is displayed with excessive decimal digits. **Root Cause** Floating-point arithmetic in Python causes small precision errors when performing calculations involving monetary values. Since Odoo's Monetary fields are based on float types, operations such as balance calculations retain unnecessary decimal places instead of rounding them correctly to two digits. **Fix** To prevent this from happening, at the moment of crafting the message to display on the chatter, it is explicitly requested to only show two decimal digits of the rounded closing difference. Opw-4483487 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#199082
This fix prevents an error from appearing when a user leaves a Discuss call before responding to a camera access request. It improves call reliability by safely handling delayed camera permission responses, especially when access is denied.
Original PR description
Before this commit, a traceback would occur of the camera access was rejected after leaving a call that requested it. This race condition could also happen in other cases where the call is left before the camera promise resolves.
This fix prevents an error when creating an Analytic Distribution in a multi-company setup where one company has no fiscal localization configured. Users can now open and create Analytic Distribution records without the screen crashing in this scenario.
Original PR description
Currently, an error occurs when a new company is created without selecting a `Fiscal Localization`, and then both companies are selected while creating a new `Analytic Distribution`. Steps to…
Currently, an error occurs when a new company is created without selecting a `Fiscal Localization`, and then both companies are selected while creating a new `Analytic Distribution`. Steps to reproduce: --- - Install `Accounting` module(without demo) - Enable `Analytic Accounting` - Create a New company and switch to it - Select both companies and Open `Analytic Distribution` and click `New` Traceback: --- `TypeError: 'bool' object is not subscriptable` At [1], we are searching by `account_type`, but if `Fiscal Localization` is not set for the current company, there will be no records in `account.account`. However, due to the multi-company setup, it still return accounts from the first company. In such cases, the `code` field is empty, which causes the `code` to be treated as False. [1]: https://github.com/odoo/odoo/blob/d155edfd729ab9b53f38939fe24b6d1e7b578083/addons/account/models/account_analytic_distribution_model.py#L55-L58 sentry-6754820454 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix keeps promotional ribbons correctly attached to product images on eCommerce product pages when customers zoom in or out. It prevents a broken-looking layout and helps maintain a polished shopping experience.
Original PR description
<b>Steps to Reproduce:</b> 1. Install Sales and eCommerce modules. 2. Go to Sales → Products, open any product, go to Sales tab, and set a Ribbon. 3. Navigate to Website → Shop, search for the…
<b>Steps to Reproduce:</b> 1. Install Sales and eCommerce modules. 2. Go to Sales → Products, open any product, go to Sales tab, and set a Ribbon. 3. Navigate to Website → Shop, search for the product and open its page. 4. Zoom in or out. <b>Issue:</b> - The ribbon on the product image becomes misaligned (shifts away from the image) when zooming in or out on the product detail page. This results in a broken visual layout. <b>Cause:</b> - A previous change in [PR #175473](https://github.com/odoo/odoo/pull/175473) unintentionally replaced the height class (h-100) with width (w-100) on ribbon container, causing layout instability during zoom operations. <b>Solution:</b> - Restore the proper layout by reintroducing h-100 to both the ribbon container and inner image div. This ensures the ribbon stays correctly positioned relative to the image regardless of zoom level. <b>opw-4854217</b> <b>Before FIX :</b>  <b>After FIX:</b> 
This fixes an issue where saving a website page with an embedded signing/payment component could create a duplicate, non-working signature box. The component is now protected from direct website editor changes, helping keep quotation signing pages reliable for customers.
Original PR description
Problem: Making `owl-component` editable causes issues. Upon saving, its content gets duplicated because the saved DOM includes both the rendered and injected content. Solution: Mark `owl-component` as non-editable to prevent modification and avoid content duplication. Steps to reproduce: 1. Navigate to Sales → Open a quotation that requires signature 2. Go to Website preview 3. Click "Sign & Pay" 4. Open Web Editor 5. Save. → A duplicate, non-functional signature box appears opw-4749129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217651
Combo products in Point of Sale now count as a single item for loyalty program rules instead of counting each included option separately. This prevents customers from receiving extra unintended discounts or points when buying combos, improving accuracy in promotions.
Original PR description
Combo lines where counted as products in the loyalty program rules, but they are part of only one product, the combo product. So when you add a combo product to the cart, it should count as one product no matter how many items are in the combo. Steps to reproduce: ------------------- * Create a combo product with 3 products options in it * Create a loyalty program that give 1 point with a minimum quantity of 2. And 100% discount on the cheapest product in exchange of 1 point * Open PoS session * Add the combo product to the cart > Observation: You get 2 discount of 100%. Why the fix: ------------ We ignore combo lines in the loyalty program rules. This way, no matter how many products are in the combo, it will only count as one product for the loyalty program rules. opw-4783013 Forward-Port-Of: odoo/odoo#213002
This change corrects a company-specific payment account used in an automated course certification test. It helps ensure the test reflects the right company setup and avoids false build failures unrelated to customer-facing behavior.
Original PR description
Steps to reproduce:- - Install `account` module. - Invoicing > Configuration > Payment Providers - Install `Demo` payment provider, check state `Test Mode` and is `Published`. - Run `test_course_certification_employee` test case. Error: “Draft Payment” belongs to company “company_1_data” and “Outstanding Account” (outstanding_account_id: 'Outstanding Receipts') belongs to another company. Cause:- - When `Demo` provider is activated, `account.payment.method.line` is created with `payment_account_id` of company `YourCompany`, but that account was not changed in the test. Solution: In `test_course_certification_employee` test, set outstanding account of company `company_1_data` for `account.payment.method.line` with code `Demo`. Runbot Build Error-229953
Users can now attach receipts to submitted expense reports without encountering an error screen. The fix improves reliability for expense submissions by checking access and attachment details before saving receipts.
Original PR description
<b>Version:</b> - 18.0 <b>Steps to Reproduce:</b> 1. Log in as Admin. 2. Install the Expenses module. 4. Go to Users > Select or Create an internal user: - Create an Employee for the user (if not…
<b>Version:</b> - 18.0 <b>Steps to Reproduce:</b> 1. Log in as Admin. 2. Install the Expenses module. 4. Go to Users > Select or Create an internal user: - Create an Employee for the user (if not already done). - Ensure Expenses is set blank. 5. Log in with this user. 6. Go to Expenses > Create a new expense. 7. Add a name and total, click "Create Report", then "Submit to Manager". 8. Go back to the expense and attempt to attach a receipt. <b>Issue:</b> - A traceback is raised when trying to attach receipt after submitting the report. **Cause:** - When setting the main attachment, the method _message_set_main_attachment_id tries to filter on mimetype assuming it's always a string. If the attachment has False value for mimetype, this leads to AttributeError: 'bool' object has no attribute 'endswith'. **Solution:** - Safely check whether the attachment exists before calling _message_set_main_attachment_id. This avoids passing an empty recordset and prevents triggering the downstream error. <b>opw-4760255</b>