Wednesday, October 1, 2025
22 changes · saas-18.3
New functionality added to Odoo
The Brunei localisation now includes official district names and codes, so businesses can use consistent address data without manual setup. It also aligns Brunei address formatting and currency display with official postal guidance, improving accuracy on customer and supplier records.
Original PR description
Added district names and codes based on government postal website, https://www.post.gov.bn/Documents/Buku%20Poskod%20Edisi%20ke%202%20(Kemaskini%2026122018).pdf Description of the issue/feature this PR addresses: Currently, the Brunei localisation does not include district names and codes, which requires users or system integrator to enter the district names manually before starting to use the system. Current behavior before PR: Partner addresses in Brunei cannot be assigned to a standardised district. District codes are missing from the localisation data. Desired behavior after PR is merged: Brunei district names and their respective codes are available in the localisation module. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228664
Enhancements to existing features
Odoo databases can now communicate correctly with IoT Boxes that report a newer fixed stable version. This helps keep point-of-sale and Belgian black box integrations working smoothly after the IoT Box versioning change.
Original PR description
In odoo/odoo#221948, we make the IoT Box version "fixed" to the last stable odoo version. We then need to make databases send/accept requests from an higher IoT Box version. Forward-Port-Of: odoo/enterprise#94330 Forward-Port-Of: odoo/enterprise#91937
Resolved issues and error corrections
Spanish POS orders using TicketBAI now automatically retry the previously failed submission when a new order is paid. This helps prevent one failed tax submission from creating a growing backlog of unsubmitted sales records.
Original PR description
Currently, the post failure of a single pos order can easily cause a backlog of more unposted orders since new orders will not be posted until the chain head is posted. Steps to reproduce ----- 1. Validate a pos order and have the TicketBAI post fail 2. Validate another pos order 3. The post for the second order is never attempted Cause ----- `_check_can_post()` ensures that new orders are not posted if the chain head was not posted successfully. During normal operation, it is common for many new orders to be paid before the user has a chance to manually retry the chain head post in the backend, causing a backlog of unposted orders. Solution ----- During `action_pos_order_paid()` retry the chain head post if is not sent. opw-4669823 Forward-Port-Of: odoo/odoo#228477
The Point of Sale now blocks keyboard-based order line edits while a popup is active, such as customer selection, notes, or coupons. This helps prevent accidental changes during checkout and makes the POS flow safer for staff.
Original PR description
Before this commit: - Even when a popup (e.g., customer selection, note, coupon) was open, unfocused keyboard inputs could still update orderline values. After this commit: - Orderline editing via keyboard is disabled whenever a popup is active. - Prevents unintended changes and ensures a safer user flow in POS. Task-5033716 Forward-Port-Of: odoo/odoo#229324 Forward-Port-Of: odoo/odoo#226300
Customers can now successfully add their selected free product when redeeming a coupon that offers a choice among tagged products. This fixes a checkout issue that prevented the reward item from being added to the cart, reducing friction in promotional campaigns.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a coupon program with a free product reward using a product tag; 2. generate coupons & copy a coupon code; 3. have 2 or more products with the tag; 4. go to /shop & add any product to your cart; 5. go to checkout; 6. apply coupon code; 7. select a free product; 8. click "Use". Issue ----- Product isn't added to the cart. Cause ----- On forward porting a fix for a similar issue in bb92ba5fbba94, it accidentally checks for the `product_id` in `request.env` instead of `request.env.context`. As no `product_id` is found, no product is added. Solution -------- Check `request.env.context` instead of `request.env`. opw-4979939 Forward-Port-Of: odoo/odoo#229157 Forward-Port-Of: odoo/odoo#224166
This fixes a problem where sale orders linked to projects could become blocked if a related analytic account had been deleted. Users can now update the Project field on affected sale orders without encountering an error, improving reliability for sales and project workflows.
Original PR description
# Issue: In a sale order, if any of the so lines contains the ID of a deleted analytic account in its analytic_distribution field, then updating the project_id field is impossible as it raises an…
# Issue: In a sale order, if any of the so lines contains the ID of a deleted analytic account in its analytic_distribution field, then updating the project_id field is impossible as it raises an error. # Cause This is caused because _compute_analytic_distribution() tries to retrieve 'root_plan_id' from all ids without checking if records exists. # Fix This commit add an exists() check on analytic.accounts retrieved from analytic_distribution field and clear the non-existing records ids from the field. # Steps to reproduce - Install sale_project and accountant modules - Check "Analytic Accounting" in the Accounting settings - Create a new project "Test P", set it up "Billable", with a new Analytic account "Test AC" (field "Project" tab "Analytic") - Create a new sale order "Test SO", add a few products and set up the Project field to "Test P". Save the sale order. - Delete the analytic.account "Test AC" - Go back on "Test SO", try to change the field "Project" - a Missing error is thrown --- Current behavior before PR: When creating a sale order and binding it to a project with an analytic account, then deleting the analytic account, the field "Project" on the sale order can't be updated anymore. Desired behavior after PR is merged: When creating a sale order and binding it to a project with an analytic account, then deleting the analytic account, the field "Project" on the sale order can be updated. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224895
Point of Sale now filters quotations and orders by the customer currently selected at checkout. This prevents staff from seeing unrelated customer documents, making order lookup clearer and reducing the chance of selecting the wrong record.
Original PR description
Before this commit, when selecting a customer in the POS and clicking Actions → Quotation/Order, all quotations and orders were displayed instead of filtering by the selected customer. This commit ensures that only the quotations/orders of the selected customer are shown. opw-5074052 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228285 Forward-Port-Of: odoo/odoo#227448
Fixed an issue where the rental schedule could hide later rental orders for products rented again with the same serial numbers. Businesses can now see the full set of rental bookings, helping avoid undercounting availability or missed follow-up on repeated rentals.
Original PR description
**Current Behavior:** With rental transfers enabled, renting a product with a serial number multiple times will result in the rental schedule only showing one of multiple rental orders for that SN.…
**Current Behavior:** With rental transfers enabled, renting a product with a serial number multiple times will result in the rental schedule only showing one of multiple rental orders for that SN. **Expected Behavior:** All rentals for the same SN should appear in the rental schedule. **Steps to Reproduce:** - Go to Rental > Configuration > Settings and enable Rental Transfers - Create a new product that is storable, can be rented, and is tracked by unique serial number - Receive 25 of the product with assigned serial numbers - Create and confirm a rental order for 25 units of product - Validate both OUT and IN transfers - Duplicate the rental order and confirm it - Check Rental > Schedule -> Odoo says 25 total units across the original and duplicate orders, but they each have 25 **Cause of the Issue:** Previously, commit ed5fd2693fc fixed a bug where all serial numbers would display regardless of whether they were involved in a rental. This introduced this bug, where only the first stock move line with a distinct serial number would be shown in the rental schedule. **Fix:** Change the "SELECT DISTINCT ON" to "sml". We can get all distinct stock move lines as we can expect SNs to appear multiple times. opw-5003247 Forward-Port-Of: odoo/enterprise#95315
Fixes several issues that could make Knowledge comments disappear, fail to load when switching locked articles, or crash in code blocks. This helps users keep comment discussions visible and accessible across article editing and read-only viewing workflows.
Original PR description
### Issue 1: Summary: When a user adds a comment inside a baseContainer element, the comment beacons created during the comment insertion can be discarded during the document normalization step. How…
### Issue 1: Summary: When a user adds a comment inside a baseContainer element, the comment beacons created during the comment insertion can be discarded during the document normalization step. How to reproduce: - Open an article in Knowledge. - Select text and change the block style from "Paragraph" to "Normal" using the powerbox. - Add a comment on the selected text using the powerbox. - Write a message in the comment thread. - Save and reload the article. Issue: - The comment beacons disappears from the editor and the user can't see it anymore. Resolution: When the editor is initialized, `div` are not yet categorized as paragraph related elements. The `comments_plugin` logic to identify valid positions for comments beacons should take that into account and allow elements which are candidates to be a paragraph related element. ### Issue 2: Summary: There was an issue where comments were not displayed when switching from a locked article to another (read-only). How to reproduce: - Create two articles and add a comment on each. - Lock both articles (so that they are effectively read-only). - Switch from one article to the other. Issue: - Comments are not displayed to the user. Resolution: When switching between read-only articles, `KnowledgeHtmlViewer` is not fully reloaded and continues using the same `CommentBeaconManager` instance for the newly opened article. As a result, comment beacons are not displayed when switching article. The simplest solution to this issue is to re-instantiate a new `CommentBeaconManager` whenever the HTML value changes to ensure comments are correctly displayed. ### Issue 3: There is an issue in the logic of `computeVerticalDimensions` to display comments. If the `top` value of a thread in the article is `0`, it will be filtered out and not displayed because `top` was used as a boolean value. Instead, it should properly consider `top` as a finite number to display the comment or not. Note: This issue is not easily reproducible because there are few configuration where a comment would have a top value equal to 0. ### Issue 4: There is a crash when inserting a knowledge comment in a `/code` block: In this previous [task], insertion in `pre` elements was filtered to prevent non-phrasing content from being inserted (as it is invalid per the html specification). To prevent a crash, knowledge comments will be disabled in `<pre>` elements, as they rely on `anchor` elements for the comment position in the article body. [task]: 216e9eb task-4984152 Forward-Port-Of: odoo/enterprise#91408
Fixes an issue where point-of-sale receipts could show the selected shipping date as the previous day for users in time zones behind UTC. This helps staff and customers see the correct delivery date on receipts when using Ship Later.
Original PR description
In this bug, the shipping date in pos receipt is set to previous dates. To reproduce the bug: 1- Setup a database with point_of_sale app installed 2- In configuration -> Setting, check Allow Ship Later option for a pos shop. 3- Change the browser timezone to a US timezone. In chrome it can be in Console -> Sensors -> Location. 4- Open POS register, select a product, choose payment and use Ship Later, to pick a date. 5- After validating the order, you can see the wrong shipping date is shown in the recipt. This is related to #215140 in which the shipping date bug is fixed when the date is picked. However, in generation of receipt a new PosOrder object is created, in which there is a need to explictly deserilizing shippingDate to avoid unwanted timezone effects. opw-5009476 Forward-Port-Of: odoo/odoo#224586
Fixes the XML field name used for linked invoice dates in Italian electronic invoicing. This prevents affected invoices with a customer reference from being rejected by the Italian exchange system due to an invalid format.
Original PR description
The name for the date in DatiFattureCollegate (56e08bb091d39a18ea1c8e7699321b953a8823e1) is wrong. It is not DataDocumento but Data as per https://fex-app.com/FatturaElettronica/FatturaElettronicaBody/DatiGenerali/DatiFattureCollegate/Data/18
How to reproduce the issue:
- With l10n_it, create an invoice and fill the customer reference field.
- Generate the xml and validate through https://fex-app.com/servizi/verifica
- The following error related to the date happens: E-invoicing (Italy) La fattura elettronica è stata rifiutata dall'SdI. File non conforme al formato : Invalid content was found starting with element 'DataDocumento'. One of '{Data, NumItem, CodiceCommessaConvenzione, CodiceCUP, CodiceCIG}' is expected. riga: 80 - colonna: 24
opw-5082016
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#227260Product pages with many images now keep the selected thumbnail centered in the image viewer, so shoppers can access all thumbnails instead of having some cut off at the screen edge. The update also improves mobile browsing by allowing easier swipe navigation through product images.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Add a bunch of extra images to a published product; 2. enable zoom-on-click via editor; 3. click on an image to zoom it; 4. scroll through images. Issue ----- With too many images added, the thumbnails on the bottom are cut off on the edges of the screen, making it impossible to click on them. Cause ----- The thumbnail row element doesn't get updated when selecting a new image. Solution -------- Define a `_updateCarousel` method which adds a `transform: translate` operation to the thumbnails, moving them such that the currently selected image's thumbnail gets centered on the screen. Call this method on mounting, and again on any render (image change). Bonus: add `touchstart` & `touchmove` hooks to enable easy swiping through the carousel on mobile. opw-4937009 opw-4908881 Forward-Port-Of: odoo/odoo#229256 Forward-Port-Of: odoo/odoo#224981
Fixes an error that could occur when users edited budget amounts after changing the report date range. Budget lines are now matched to the correct monthly period, preventing duplicate incomplete entries and allowing users to continue updating budgets reliably.
Original PR description
Currently, an error occurs when user editing the budget report items. Steps to Reproduce [Video](https://drive.google.com/file/d/1bz0GEQjwxQrckzcEHdYPfvaA5M43lmFF/view): - Install the `Accounting`…
Currently, an error occurs when user editing the budget report items. Steps to Reproduce [Video](https://drive.google.com/file/d/1bz0GEQjwxQrckzcEHdYPfvaA5M43lmFF/view): - Install the `Accounting` module. - Go to `Profit and Loss` > `Budget` and `create a budget`. - Select `custom dates (e.g., start: 01/01/2025, end: 12/10/2025)` and change the amount of a budget line. - Change the `date range (e.g., start: 01/10/2025, end: 12/10/2025)` and change the amount again. - `Switch back to the first date range` (start: 01/01/2025, end: 12/10/2025) and try changing the amount once more. `TypeError: unsupported operand type(s) for +: 'float' and 'NoneType'` This error occurs when a user editing the budget report items. When user enters a date period, the system creates budget items for the first date of every month within that range. If the user then changes the date period to the next date of the same month, the system attempts to fetch the existing budget item `[1]` for that range. However, due to the start date alignment, it fails to fetch the correct budget item and instead creates an extra one `[2]`. Later, when the system checks again from the first date of the same month as the start date, it finds this extra budget item, for that the amount is None, which raises the error `[3]`. This commit ensures that when fetching existing items and generating the start month dates `[4]`, the system always uses the first day of the month as the `start date` so that the flow is maintained.. [1]- https://github.com/odoo/enterprise/blob/1df83837a2aec4801b34a9a7ab0cd68f640b4fd6/account_reports/models/budget.py#L44-L49 [2]- https://github.com/odoo/enterprise/blob/1df83837a2aec4801b34a9a7ab0cd68f640b4fd6/account_reports/models/budget.py#L75-L79 [3]- https://github.com/odoo/enterprise/blob/1df83837a2aec4801b34a9a7ab0cd68f640b4fd6/account_reports/models/budget.py#L72 [4]- https://github.com/odoo/enterprise/blob/1df83837a2aec4801b34a9a7ab0cd68f640b4fd6/account_reports/models/budget.py#L58-L61 sentry-6883207225 Forward-Port-Of: odoo/enterprise#95090
Shop Floor now displays manufacturing by-products in the right place and with clearer quantity information. This reduces confusion for operators by hiding irrelevant location details and opening the correct creation dialog when adding tracked by-products.
Original PR description
Shop Floor by-products fixes: - show by-products not linked to a workorder only on mo card - do not show locations for by-products - always show quantity done / to consume quantity - clicking (+) on tracked by-products now opens the create quant dialog rather than the quants list view task: 4781451
This fixes an issue where engineering change orders could not correctly record very small bill of materials quantity updates when units of measure allowed more than two decimals. Businesses using precise measurements can now track component quantity changes accurately during product revisions.
Original PR description
Steps to reproduce the bug:
- Go to Decimal Accuracy → Product Unit of Measure → set digits to 4
- Go to Units of Measure Categories → select a unit → set rounding to 0.0001
- Create a storable product “P1” with a BoM:
- Component C1: 1.0000 unit
- Create an ECO for the BoM with type BoM update
- Start the revision
- Go to V2
Problem:
You cannot update the quantity of C1 to 1.0003 (for example) because the system uses the default 2 digits instead of the UoM digits.
opw-5082488
Forward-Port-Of: odoo/enterprise#95470
Forward-Port-Of: odoo/enterprise#95180The Time Off view now uses the correct employee profile context when opened from My Profile. This prevents users from seeing a Missing Record error and allows them to access their time off information reliably.
Original PR description
**Steps to reproduce (without demo data):** - Install hr_holidays - Go to "My Profile" - Open "Time Off" **Issue:** Accessing Time Off from a user profile triggers a `Missing Record` error. **Cause:** The system was passing the user’s active_id to the employee record incorrectly. **Fix:** Now, when the context's active_model is 'hr.employee', the correct active_id is applied. **Commit issue:**https://github.com/odoo/odoo/pull/225839
This fixes an issue that prevented portal users from creating project tasks by sending emails to a project alias. Restoring this flow helps external collaborators and customers submit work requests without needing direct backend access.
Original PR description
The new safety belt introduced in 745f3accaf775550294d6f1bf562a0dcc15f7a08 made it impossible for portal users to create tasks by sending emails to the project alias. @moduon MT-11332 Forward-Port-Of: odoo/odoo#228986 Forward-Port-Of: odoo/odoo#225321
Fixed an issue where self-ordering kiosks could open to a blank screen when a point of sale used only a parent category with products in its child categories. The kiosk now selects an available child category so customers can browse and order normally.
Original PR description
Problem: When the available categories for a point of sale contain one parent category and its child categories and the parent category itself does not have any products, the code filters out the top…
Problem: When the available categories for a point of sale contain one parent category and its child categories and the parent category itself does not have any products, the code filters out the top categories as those that have no parent category. If, in such a case, no products belong to the parent category itself, the selected category is undefined which leads to a blank white screen and the javascript error visible on the console. Purpose: If there are no top categories, the screen should ideally load the current category computed before. This fix leads to the one of the child categories being the selected category and the kiosk screen loads properly Steps to Reproduce on Runbot: 1. Create a point of sale. Go to Settings, choose no presets and “Kiosk” in the self-ordering option. 2. Create a parent POS category and two child POS categories. 3. Ensure there are products belonging to the two child categories and none to the parent category 4. Open settings for the POS and choose only these three categories in the “Restrict Categories” section. 5. Go to the point of sale and open the kiosk. Click on “Order Now”. The white screen appears and the js traceback error is visible on the console opw-5058245 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes survey descriptions and end messages so embedded media like videos can be shown properly when respondents open a shared survey link. It prevents content added in the editor from relying on editor-only components that are not available in the public survey view.
Original PR description
Embedded components do not render when the html field content is displayed outside the editor, as their mechanism relies on the editor plugin. Solution: --------- Disable embedded components for the…
Embedded components do not render when the html field content is displayed outside the editor, as their mechanism relies on the editor plugin. Solution: --------- Disable embedded components for the survey messages (Description and End Message). Steps to reproduce: ------------------- * Create a new survey * Add a video as End Message or Description * Use the share link to view de survey * Video not showing Cause of the issue: ------------------- The new web_editor has a plugin system, and one option that is enabled by default is embedded_components. This option has been introduced in: https://github.com/odoo/odoo/commit/03f495c696030214c17e6479076571823513f60e According to the description: "It is forcibly set to false in HtmlMailField since embedded components can only be rendered inside Odoo." Observation : ------------ similar fix: https://github.com/odoo/odoo/commit/1446167e482745c71725563e56411948c3dd1f41 opw-5005752 Forward-Port-Of: odoo/odoo#224808
Active payment providers can no longer have their linked payment journal removed from the journal settings. This prevents payment failures caused by missing journal information and helps keep payment processing stable for companies using branch setups.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have an active payment provider; 2. create a branch company; 3. set payment provider's company to branch; 4. leave Payment Journal unchanged (parent company Bank); 5. go to Accounting / Configuration / Accounting / Journals; 6. open Bank journal; 7. open "Incoming Payments" tab; 8. enable the "Payment Provider" column; 9. unset the payment provider on the active provider's line & save; 10. attempt paying using the provider. Issue ----- > Error: psycopg2.errors.NotNullViolation: > null value in column "journal_id" of relation "account_payment" violates not-null constraint Cause ----- We shouldn't be able to change the related journal of active providers. Solution -------- Make the field read-only if the payment method is active. opw-5045000 Forward-Port-Of: odoo/odoo#229342 Forward-Port-Of: odoo/odoo#225187
Customer statement emails sent from child contacts now include the correct PDF details instead of an empty attachment. The statement button is also hidden when there are no transactions or nothing is due, reducing confusion for accounting users.
Original PR description
**Steps to reproduce:** 1. Go to Accounting > Customers > create a company with child contact (invoice) (both having name and email). 2. Create an invoice with the child contact as customer and…
**Steps to reproduce:** 1. Go to Accounting > Customers > create a company with child contact (invoice) (both having name and email). 2. Create an invoice with the child contact as customer and confirm it. 3. Go to the child contact and open the Customer Statement smart button. 4. Download the PDF → data is shown correctly. 5. Send the statement → the attachment in the sent mail is empty. **Issue:** - When sending customer statements via email from a child contact, the generated PDF attachment contains no data, showing empty amounts and transactions. - Additionally, the "Customer Statement" button was still visible even when the total due was zero. **Cause:** - The button visibility condition checks for `total_due == 0.0 and not has_moves`, which didn’t properly cover all use cases. **Solution:** - Update button visibility condition to: `invisible="not has_moves or total_due == 0"` ensuring it is hidden when there are no moves or the total due is zero. **opw-5009182** Forward-Port-Of: odoo/enterprise#95356 Forward-Port-Of: odoo/enterprise#93162
When warehouse staff split a package during barcode picking, the new split line now keeps the original reserved source package. This prevents package information from being lost and helps ensure partial deliveries remain accurate and traceable.
Original PR description
### Before this PR: - Put a package in WH/Stock with quantity 100 - Create delivery for partial quantity for example 50 - Go to app barcode - Try to split the package into two different packages scanning another destination Package - The splitted line will be created with empty package instead of the package already reserved before ### After this PR: Scanning another destination package , the new line created splitting the old one will have the package_id Forward-Port-Of: odoo/enterprise#91930 Forward-Port-Of: odoo/enterprise#81170