Daily updates from Odoo
Friday, October 10, 2025
25 changes · saas-18.3
Resolved issues and error corrections
Sale orders and invoices no longer crash when a customer contact has no name and sale warnings are enabled. This keeps sales and billing workflows running smoothly even when contact records are incomplete.
Original PR description
When creating a Sale Order or Invoice for a partner without a name, a traceback occurs. Steps to reproduce the error: - Install ``sale_management`` with demo data - Enable ``Sale Warnings`` from settings - Open ``Azure Interior`` Contact > In Contact, Add Contact > Type: invoice > Save & close - Create a sale order with the newly created partner AND - Create an invoice with the newly created partner Traceback: ``TypeError: unsupported operand type(s) for +: 'bool' and 'str'`` https://github.com/odoo/odoo/blob/7a1b27e5985b3b16768bea450c51226ae3659c76/addons/sale/models/sale_order.py#L822 https://github.com/odoo/odoo/blob/7a1b27e5985b3b16768bea450c51226ae3659c76/addons/sale/models/account_move.py#L59 Here, ``partner_id.name`` is ``False``, which leads to string concatenation with a boolean in sale warning messages and results in the above traceback. sentry-6912482256 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures Indian HR leave records calculate durations correctly when sandwich leave rules include consecutive non-working days or public holidays. It also corrects half-day leave so it is counted as 0.5 days instead of a full day, helping payroll and time-off balances stay accurate.
Original PR description
**Steps to reproduce:** - Install l10n_in and l10n_in_hr_holidays module - Time off > configuration > Public holidays - Create a public holiday for Independence Day (15/08/2025) - Go to Time off >…
**Steps to reproduce:** - Install l10n_in and l10n_in_hr_holidays module - Time off > configuration > Public holidays - Create a public holiday for Independence Day (15/08/2025) - Go to Time off > configuration > 'Time off Types', - Create a Time off type with - 'Sandwich leave' ticked and `Take Time Off in` to half a day - Go to Time off > Management > Time off - Case 1: Create a paid time off leave for the employee from 13/08 to 17//08/2025 - Case 2: Create a paid time off with any date and mark it as a half-day **Observation:** - Case 1: You will see Duration 3 days with the sandwich leave policy. - Case 2: Half-day leave shows 1 day instead of 0.5 **Root Cause:** - Case 1: For the sandwich leave rule, here we checked only one day after and before, leave start and leave end, respectively. It will cause an issue if an employee applies leave that starts or ends with 3 non-working days. https://github.com/odoo/odoo/blob/5d2f1510c08d5570fc2c6c8de0cb4042bacf12d6/addons/l10n_in_hr_holidays/models/hr_leave.py#L39-L46 - Case 2: We forcefully added a 1-day leave, without checking if the leave is half day or not. https://github.com/odoo/odoo/blob/5d2f1510c08d5570fc2c6c8de0cb4042bacf12d6/addons/l10n_in_hr_holidays/models/hr_leave.py#L19 **Solution:** - Case 1: Extend the sandwich leave logic to check every day before and after until a working day is found. - Case 2: Fixed duration calculation to add 0.5 for half-day leaves. opw-5025766 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226883
Users visiting an embedded course link that points to a course category instead of a lesson no longer see an error page. The system now redirects them safely to the course homepage, improving reliability for website visitors.
Original PR description
When users try to access a `slide ID` that is not included in `channel_slides_ids`, a traceback occurs. Steps to reproduce: --- - Install `website_slides` module - Go to the Website and click on the…
When users try to access a `slide ID` that is not included in `channel_slides_ids`, a traceback occurs. Steps to reproduce: --- - Install `website_slides` module - Go to the Website and click on the `Courses` menu. - Then go to `/slides/embed/<int:slide_id>` route. (http://localhost:8069/slides/embed/7) - The error will occur. Traceback: --- `ValueError: 7 is not in list` At [1], `slide_content_ids` contains the IDs of `channel content`. However, we are trying to access a slide from the `channel category` in URL. As a result, at [2], when attempting to find the index of the slide in `slide_content_ids`, an error occurs because the slide ID actually belongs to `slide_category_ids` and is not present in `slide_content_ids`. Solution: --- Added a special case for category slides — if the slide is a category, redirect to the channel homepage. [1]- https://github.com/odoo/odoo/blob/482bb19e103de9ddbe1b1942b94b33d3da38889b/addons/website_slides/controllers/main.py#L120 [2]- https://github.com/odoo/odoo/blob/482bb19e103de9ddbe1b1942b94b33d3da38889b/addons/website_slides/controllers/main.py#L121 sentry-6572999628 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225374
This fixes a timing issue that could make a stock barcode test fail randomly when validating an operation right after saving changes. The validation step now waits for the right screen state, improving automated test reliability without changing day-to-day user behavior.
Original PR description
Sometime, the test `test_scrap_change_source_location` could fail randomly. The issue happens in last few steps of the tour. What we do is: - We edit a move line lot in the form view; - We save it; -…
Sometime, the test `test_scrap_change_source_location` could fail randomly. The issue happens in last few steps of the tour. What we do is: - We edit a move line lot in the form view; - We save it; - We validate the operation. The validation is done by a barcode scan (`OBTVALI`) but since [1](https://github.com/odoo-dev/enterprise/commit/b3a855a870d1861515abaff8683081a39f95558f), barcodes scanned when the user is somewhere else than in the barcode lines view are skipped. With a little bit of bad luck, the tour scans `OBTVALI` while the save from the form view is not finished yet and thus, the scanned barcode is ignored. To reproduce that, run the test `test_scrap_change_source_location` locally in debug mode and add a throttling (eg.: Fast 4G) before to run the tour. To solve the issue, finetune the `validateBarcodeOperation` default trigger, so the error won't happen in this tour and other similar contexts. Runbot build error: [232331](https://runbot.odoo.com/odoo/runbot.build.error/232331) Forward-Port-Of: odoo/enterprise#96542
Changing the quotation template on a sales order now removes the old linked quote calculator spreadsheet. This prevents users from accidentally working with pricing details from the previous template and keeps the sales order aligned with the selected template.
Original PR description
Step to reproduce: - Create a new SO - Add a customer and quotation template to the order - Click on quote calculator smart button - Return to sale order (click on SO number in top left) - Change the quotation template - Result: it does not change the quote calculator that is linked to the new quotation template Cause: - Clicking on Quote Calculator creates a copy of the quotation template spreadsheet and links it to the SO. https://github.com/odoo/enterprise/blob/8bc6098335d283e6d210dc788463a8ef8c559b14/spreadsheet_sale_management/models/sale_order.py#L30-L35 - When the quotation template is later changed, the spreadsheet linked to the old template remains attached to the SO. Fix: - On changing the sale_order_template, the old spreadsheet should be unlinked from the SO. - Keeping it linked is inconsistent, as it does not matches the current template opw-4998587 Forward-Port-Of: odoo/enterprise#95652 Forward-Port-Of: odoo/enterprise#93970
Fixes invoice tax calculations when multiple price-included taxes are used and only some affect later tax bases. This prevents incorrect tax report warnings and improves the accuracy of invoice totals, tax bases, and discount calculations, with only minor rounding differences possible.
Original PR description
**Issue** When creating an invoice with two price-included taxes, one that affects the base of subsequent taxes (`include_base_amount=True`) and another that does not, the tax computation is…
**Issue** When creating an invoice with two price-included taxes, one that affects the base of subsequent taxes (`include_base_amount=True`) and another that does not, the tax computation is incorrect. This leads to inconsistent base amounts and triggers a warning in the tax report, particularly visible in the Tax Return Report. **Steps to Reproduce** 1. Create two taxes with `price_include=True`: Tax1 with "Affect Base of Subsequent Taxes" disabled Tax2 with it enabled 2. Add both taxes to the same invoice line and confirm the invoice 3. Open the Tax Report and filter by the invoice date 4. The report shows an inconsistency because the computed base is wrong **Root Cause** The batching logic separates taxes into groups when their properties differ. In this case, because the two taxes have different `include_base_amount` values, they are split into different batches. Since batching drives how price-included taxes are reversed to compute the base, splitting the batch leads to misinterpreted base amounts and incorrect tax calculations. **Fix** Adjusting batching conditions to allow taxes to be grouped together even if their `include_base_amount` flags differ. This ensures that price-included taxes are handled consistently and the base is computed correctly across all taxes in the group. Opw-4863100 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221401
The Documents app no longer shows an unused tooltip field on document tags, reducing confusion for users managing tag settings. The field remains safely in the background for compatibility in this stable version, but is marked as deprecated for future removal.
Original PR description
The 'tooltip' field was introduced on document tags categories, but after couple of refactors it ended up unused on document tag. As we cannot remove fields from the data model in stable, this commit removes tooltip from the view and marks it as deprecated in the code. opw-4567814 ## Stems from https://github.com/odoo/odoo/pull/210147 https://github.com/odoo/enterprise/pull/79496 # Merge plan - hide `tooltip` in stable - remove `tooltip` in master Forward-Port-Of: odoo/enterprise#86504
Sales order lines now keep the selected packaging unit, such as a pack of 6, when a user reviews or updates a product variant. This prevents quotes from accidentally reverting to single units, helping preserve accurate quantities and customer pricing.
Original PR description
## Versions
18.2+
Note: 18.4 needs `product.uom_id` to be replaced by `product.uom.id` to work properly.
## Issue
On a SO, if a product has variants and packaging is allowed, modifying the variant resets the packaging to units.
## Steps to reproduce
*Ensure "Units of Measure & Packagings" is enables in Sales' app's settings*
- Create a new product
- Under "Attributes & Variants" tab, add the following:
- Color: add 2 colors;
- Legs: add 2 legs;
- Under "Sales" tab, select "Pack of 6" for "Packagings" (under "Upsell & Cross-Sell" section);
- Create a new quote and add that new product:
- Change its "Unit" for "Pack of 6";
- Modify the product variant by clicking the pen button next to the product name (appear on hover):
- Click "Confirm" (no changes needed);
- See the order line's product's units change back to "Units".
opw-4814166
Forward-Port-Of: odoo/odoo#224574This fixes an issue where dragging from text inside a table cell could select the whole cell before all of its content was selected. Users now get more accurate table selection behavior when editing content, reducing accidental cell selections.
Original PR description
Current behavior before PR: - Create an m x n table. - Write some text in a cell. - Put cursor at the end of text. - Try to select cell by moving mouse rightwards. Notice that the cell is selected although the cell content is not fully selected. Desired behavior after PR: This PR backports commit [1] to ensure that single cell is selected only if the cell content is fully selected. [1]: https://github.com/odoo/odoo/commit/09d369e118f622f30149f46702f58c656a3cee04 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230133 Forward-Port-Of: odoo/odoo#230071
Batch invoice sending now applies Peppol only to invoices that are actually eligible for it. This prevents invoices meant to be sent by email, such as those for non-Peppol customers, from being incorrectly routed to Peppol and failing instead of being delivered.
Original PR description
…ng methods When sending invoices in batch with multiple sending methods (for example 1 by Peppol, 2 by Email), Peppol was wrongly set on invoices where it didn't make sense. Steps to reproduce: 1. Go into a Peppol compatiable company (Eg: Belgium) 2. Go into settings, enable Peppol. 3. Create & post two invoices: one to an US partner, the other one to a Peppol partner (For example a belgian partner with a vat set.). Make sure to set the email on both. 4. Send them in batch: the wizard says 1 by Peppol, 2 by Email, which is correct. 5. If you send them, the one to the US partner that is not supposed to go through Peppol will end up in error, with the email not sent either. Root cause: We are doing some Peppol checks before checking if it actually make sense to apply this sending method on the move. task-none (reported from our production)
This fix ensures the date picker properly resets when users move from one journal entry to a new one. It prevents accounting entries from staying unsaved or missing their draft title when the same prior-month date is selected again.
Original PR description
Steps to reproduce ================== - Install accounting - Go to Accounting > Accounting > Journal Entries - Create a new record - Select an Accounting Date in the previous month - An onchange is called and the title is changed to draft - Save the record - Click on New - Select the same date - The onchange isn't triggered - Save the record - The record stays dirty and the title is missing Cause of the issue ================== https://github.com/odoo/odoo/commit/44f69ae726b1ff8876c38e858c64fed0f5b1a766 lastAppliedStringValue should be reset inside computeBasePickerProps Solution ======== We backport the code from 19.0 where this was fixed opw-5145113
This fixes an incorrectly configured error message in the Expenses app. Users should now see the intended warning instead of a broken or confusing error when this situation occurs.
Original PR description
in 953fac5, the new error was not given the proper arguments Forward-Port-Of: odoo/odoo#229488
The point of sale scan button now opens the camera even when an order is selected on the ticket screen. This helps staff scan QR codes without needing extra navigation, reducing friction during checkout or order handling.
Original PR description
Before this commit: = - The scan button did not function when an order was selected. After this commit: = - The scan button now opens the camera to scan a QR code even when an order is selected. Task: 4778136 Forward-Port-Of: odoo/odoo#211875
This update removes an automated test that was causing random failures in Odoo's build checks for version 18 releases. It does not change customer-facing website shop behavior, but helps keep validation runs more reliable for maintenance releases.
Original PR description
Versions -------- - 18.0 - saas-18.2 - saas-18.3 - saas-18.4 Issue ----- The `test_toggle_contact_us_button_visibility` causes random errors in runbot. Cause ----- Unsure, but with commit 26d22fc975e3f removing jQuery from `VariantMixin`, the random error no longer seems to pop up. Solution -------- Remove the test for versions before 19.0. runbot-145473 Forward-Port-Of: odoo/odoo#230728
SEPA direct debit payments now correctly validate whether a payment mandate is still active. This prevents valid future-expiring mandates from being wrongly rejected and helps avoid unnecessary payment failures.
Original PR description
The check to ensure that the mandate used in a token payment is still valid had two issues: - It was comparing a date (the mandate's end date) with a datetime. - It was incorrectly rejecting mandates expiring in the future, while it should have done the opposite. Forward-Port-Of: odoo/enterprise#96426 Forward-Port-Of: odoo/enterprise#96143
Sales confirmations using Gelato now create a temporary draft order first, then only confirm it after the sale is safely completed. This prevents duplicate Gelato orders when payment or order processing is retried because of concurrent updates.
Original PR description
In case on a concurrent update happen in the same transaction as the sale order confirmation (was observed during payment transaction post-processing), we may currently create duplicate Gelato orders on each retry. This commit avoid duplicate order creation by splitting the Gelato order creation in two steps: - during the sale order confirmation we create a 'draft' order on Gelato - on post-commit/post-rollback we either try to confirm or delete the Gelato draft order. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228107
Appointment video call links now use the website linked to the appointment type, so customers receive links with the correct company website domain. This prevents incorrect meeting URLs in multi-company setups with separate websites.
Original PR description
**Steps to reproduce:** - Create 2 companies - Create a website for each company - Set a custom website domain on the second one - Create appointement type for each website - Create an appointement on both websites - The link created for the video call has the wrong base for one of them **Issue:** Appointment `get_base_url` finds its base_url without considering the current website. **Fix:** Compute the base_url according to the appointement type to ensure the current website is taken into account. opw-4880715 Forward-Port-Of: odoo/enterprise#92734
Sales orders with multiple global discounts now create the correct number of discount lines. This prevents confusing extra lines on orders and keeps tax and discount calculations clearer for users.
Original PR description
Because of the grouping on the computation_key in the taxes engine, when a second global discount was applied on a SO, it was creating two additional lines instead of one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures that pricing rules based on another pricelist must actually specify which pricelist to use. It prevents incorrectly calculated prices when rules are created outside the standard screens, improving pricing reliability across sales and point of sale flows.
Original PR description
Before this commit, only a view-level required attribute ensured that pricelist items with `base=='pricelist'` have a `base_pricelist_id` set. Creating pricelist items from a custom view or the API or the shell could result in missing values for this field, causing `_compute_base_price` to incorrectly assume that `base=='list_price'`` This commit introduces a new constraint ensuring any pricelist whose price is `base`d on an "Other Pricelist" has a value for `base_pricelist_id`. Note: in the views, `base_pricelist_id` is required if `compute_price == 'formula' and base == 'pricelist'` but the first condition is not neeeded because `_onchange_compute_price` sets `base` to `'list_price'` when `compute_price!='formula'` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230438
Social Marketing previews now correctly recognize URLs that include comma-separated values in their parameters. This prevents links from being cut off in post previews, helping users verify and publish accurate social content.
Original PR description
**Steps to reproduce:** - Go to `Social Marketing` app. - Click on `New Post`. - Select Facebook for preview (should not matter). - Write a message with an URL which have comma-separated parameters. (e.g 'TEST URL https://example.be:8080/path/res-123/ext/?param1=v1,v2,v3') - URL is cut on the first comma in the preview. **Issue:** URL regex did not match URLs containing comma-separated query parameters, causing them to be truncated. **Fix:** Updated the regex to include commas. opw-5042131 Forward-Port-Of: odoo/enterprise#94220
Time off requests that span consecutive allocations now account for public holidays correctly during balance checks. This prevents public holidays from being mistakenly treated as extra leave days, reducing incorrect excess leave warnings or calculations.
Original PR description
### Steps to reproduce: - Install Time off apps - Create two consecutive allocations (e.g. one for 2025 and one for 2026) - Create a leave that overlap with the two allocation (e.g. from 8th Dec to…
### Steps to reproduce: - Install Time off apps - Create two consecutive allocations (e.g. one for 2025 and one for 2026) - Create a leave that overlap with the two allocation (e.g. from 8th Dec to 3rd Jan) - Create a public holiday at the beginning of the second allocation (e.g. on 1st Jan 2026) ### Cause: When we are checking the leave duration after having a public holiday the will return the attendance without the public holidays duration so when subtracting the attendance duration from the leave duration we will have a remaining amout equals to the public holiday duration and it will be considered as excess days. https://github.com/odoo/odoo/blob/06e47d8601ba56b1650eeaeef71ebd7a4af39b8b/addons/hr_holidays/models/hr_employee_base.py#L228-L230 https://github.com/odoo/odoo/blob/06e47d8601ba56b1650eeaeef71ebd7a4af39b8b/addons/hr_holidays/models/hr_employee_base.py#L246-L254 ### Fix: We check for public holidays in the interval we are fetching its attendance to avoid assuming it is an excess days in the leave opw-5006119 Forward-Port-Of: odoo/odoo#230600 Forward-Port-Of: odoo/odoo#225433
Cashiers can now type password digits directly on a keyboard when the number entry popup is open, instead of being limited to the on-screen buttons. This makes cashier switching and password entry faster and more convenient in Point of Sale.
Original PR description
Before this commit, when the NumberPopup was open (for example, when entering the cashier password), the keyboard input was ignored because the overlay manager blocked all keyboard events while any popup was active. As a result, it was only possible to use the on-screen number buttons. After this commit, the keyboard input is allowed when a NumberPopup is open, enabling users to type the password directly using the keyboard. opw-5152235 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230626
Fixes a problem that could show an error after users validated the last available batch payment during bank reconciliation. When no batch payments remain, the screen now switches to matching existing entries so accounting users can continue their workflow without interruption.
Original PR description
Issue: Error is raised when there are no batch payments found in `saveSearchState()` Purpose of this PR: We display the match existing entries if there are no batch payments found. Steps to Reproduce on Runbot: install accounting make a batch payment reconcile single batch payment with statement line while on Batch Payments Tab opw-4807527 Forward-Port-Of: odoo/enterprise#87388
This fixes an issue where related list fields were not displayed properly in generated reports. Reports that include these fields should now show the expected information, improving accuracy for business documents.
Original PR description
For now, `One2Many` fields are not displayed correctly in reports. This is because for other types of fields (`ManyToMany`, `ManyToOne`, etc.), there are Converter classes (`ManyToManyConverter`) `ir.qweb.field.many2many` that implement `value_to_html`. However, for `OneToMany` fields, no implementation is present. This commit adds a `OneToManyConverter`, which is essentially the same as the `ManyToMany `one. opw-5098466 Forward-Port-Of: odoo/odoo#230675 Forward-Port-Of: odoo/odoo#229289
Fixed an issue where changing a coupon reward on a confirmed sales order could leave the coupon with the wrong remaining points. Coupon balances now correctly reflect the reward currently applied, helping avoid customer credit discrepancies.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10…
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10 points; 5. use coupon code on a confirmed order; 6. select 10% discount reward; 7. change to a 50% discount reward; 8. check coupon point total. Issue ----- Even though the 5 point reward was used, only 4 out of 10 points remain. Cause ----- When updating the reward line of a confirmed order, it keeps track of point cost changes before & after a write. Its purpose is to restore back the point difference on the coupon record. The issue is that while point changes are stored, coupon changes are not. When updating reward lines, `_reset_loyalty` is used, which removes the `coupon_id` from the lines. As a consequence, attempting to restore the point difference on `line.coupon_id` after an update, it writes to an empty record. Solution -------- Store both coupons & their used points before write. After write, restore the previous points to the previous coupon, and subtract the current point cost from the current coupon. This way, any combination of coupon/point changes should have the points updated as expected. opw-4910922 Forward-Port-Of: odoo/odoo#230907 Forward-Port-Of: odoo/odoo#222054