Tuesday, September 30, 2025
20 changes · 18.0
New functionality added to Odoo
This update adds standard Brunei district names and codes so customer and partner addresses can use consistent location data. It also aligns Brunei address and currency formatting with official postal guidance, reducing manual setup and improving local accuracy.
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
Enhancements to existing features
This update lets developers extend existing view settings without replacing them entirely. It reduces the risk that customizations accidentally overwrite earlier configuration, making upgrades and inherited views easier to maintain.
Original PR description
This commit introduces a new `merge` attribute to the `<attribute>` tag, allowing developers to safely merge existing dictionary-based or list-based attributes in XML view inheritance. Problem:…
This commit introduces a new `merge` attribute to the `<attribute>` tag, allowing developers to safely merge existing dictionary-based or list-based attributes in XML view inheritance.
Problem:
Currently, when a developer needs to extend an attribute like `options` or `domain` in an inherited view, they must completely redefine the attribute, which can lead to unintended overwrites of properties set in the base view. For example, to add a new option, one must copy all existing options, which is tedious and brittle.
Solution:
The new `merge` attribute provides a declarative way to extend these attributes. When specified on an `<attribute>` tag, it intelligently merges its value with the existing attribute value on the target node. For dictionary-based attributes like `options`, it performs a dictionary update. For list-based attributes like `domain`, it extends the list.
Usage Example:
Given an existing field with a base `options` attribute: `<field name="supplier_id" options="{'no_open': 1, 'no_create': 1}"/>`
A developer can now extend this in an inherited view without overwriting: `<attribute name="options" merge="{'list_view_ref':'cm_product.cm_product_supplierinfo_tree_view'}"/>`
The result will be a combined `options` attribute: `options="{'no_open': 1, 'no_create': 1, 'list_view_ref': 'cm_product.cm_product_supplierinfo_tree_view'}"`
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-prResolved issues and error corrections
Customers can now choose in-store pickup for products that are out of stock when the product is configured to keep selling anyway. This prevents valid checkout options from being blocked and keeps pickup behavior aligned with store inventory settings.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Publish the "Pickup in store" delivery method; 2. have an out-of-stock product with "Continue selling" enabled; 3. go to the product's shop page; 4. add to cart; 5. try to check out using "Pickup in store" delivery method. Issue ----- Delivery method cannot be selected. Cause ----- The `website_sale_collect` module currently only checks whether the product is in stock, and not whether the product is allowed to sell when it's out of stock. Solution -------- Check the `allow_out_of_stock_order` in `_get_unavailable_order_lines` and `format_product_stock_values`, so that the `in_stock` value used to check availability is `True` iff the products are in stock or have `allow_out_of_stock_order` enabled. opw-5080295
The Point of Sale now prevents keyboard input from accidentally changing order lines while a popup is open, such as customer selection, notes, or coupons. This reduces unintended order changes and makes checkout workflows safer and more predictable 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
The point of sale preparation display now shows free-text details entered on order line attributes. This helps kitchen or preparation staff see customer-specific instructions directly on the order line, reducing missed customizations.
Original PR description
draft to be updated
Customers and site editors can now press Enter while choosing or editing a product size on the shop page without triggering an error. This prevents an unexpected checkout browsing interruption and makes product option selection more reliable.
Original PR description
Before this commit: Pressing the Enter key while selecting a product size option on the /shop page crashed. After this commit: This fix ensures the Enter key is properly handled and prevents unexpected crashes during product option selection. task-4795501
Spanish Facturae electronic invoices now preserve the correct number of decimals for product unit prices instead of rounding only to the currency precision. This prevents rounding differences and incomplete or incorrect invoice XML values when products use more detailed pricing.
Original PR description
It is possible for a product to have more decimals than the currency, but the facturae always rounded according to the currency. This would sometimes lead to both rounding errors and incomplete or incorrect values on the generated XML. This commit rounds product prices according to the unit price decimal while leaving the other computed field untouched as to not disturb the correct computation elsewhere. As this file was changed in 18.0 another PR was needed: https://github.com/odoo/odoo/pull/209623 task-4650439
Product image galleries now keep the selected thumbnail centered when shoppers zoom and browse through many images. This prevents thumbnails from being cut off at the screen edge and adds smoother mobile swiping, making product browsing easier.
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
This fix prevents small rounding differences from building up during inventory revaluation calculations. It helps avoid incorrect negative valuation amounts, improving the reliability of stock accounting figures.
Original PR description
Before this commit, the remaining_value_unit_cost was rounded before any computation. In the case where the numer of layers with remaining value and remaining quantity increase, the rounding error introduced by that rounding quickly explodes, leading to a negative remaining_value during revaluation computation. After this commit, the remaining value is rounded at the end, after the computations and the checks. This ensures that the rounding error remains constant and does not accumulate over the execution of the method. opw-4901966 Forward-Port-Of: odoo/odoo#222690
Uploaded file fields on Field Service worksheets are now shown when customers or users open the worksheet report for signing. This prevents missing attachment information during the signing process and keeps worksheet records complete and visible.
Original PR description
Steps to reproduce: ------- - Install industry_fsm_report module - Open FSM app - Select worksheets from settings in the configuration - Go to worksheet templates in the configuration - Create a worksheet template - Click the design template button. You arrive in the studio - Add file field and close it - Create a new task and select a newly created template in the worksheet template - Click the worksheet button in the control panel - Upload a file and save it - Click on the sign report button - Here file field is not visible Issue: ------- The file field is not visible in the worksheet portal. Cause: ------ The view of the file field is not created for the worksheet portal. Solution: ------- Created the view of the file field to display in the worksheet portal. task-3691529 Forward-Port-Of: odoo/enterprise#56035
Fixes an issue where editing budget amounts after changing report date ranges could trigger an error. Budget records are now matched consistently by month, preventing duplicate incomplete entries and keeping budget updates reliable.
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
Fixes several issues that could hide or break comments in Knowledge articles, including after reloading, switching between locked articles, or commenting near the top of a page. This helps users keep discussion context visible and avoids crashes when using comments around code blocks.
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
Corrects how discounts are rounded when creating Mexican global invoices, preventing rejected invoices caused by small rounding differences. This helps users successfully validate invoices with discounts that previously triggered CFDI total mismatch errors.
Original PR description
Steps to reproduce: ------------------- * Create an invoice with the following line: * Unit price: 47.25, Qty: 1, Taxes: 16%, Discount 50% * Confirm, create a global invoice > Observation: Error ```…
Steps to reproduce: ------------------- * Create an invoice with the following line: * Unit price: 47.25, Qty: 1, Taxes: 16%, Discount 50% * Confirm, create a global invoice > Observation: Error ``` Code : CFDI40108 Message : El TipoDeComprobante es I,E o N, el importe registrado en el campo no es igual al redondeo de la suma de los importes de los conceptos registrados. ``` Why the fix: ------------ The issue occurs because the `descuento` value, originally 23.625, is now being corrected to 23.615 which leads to `importe` having a value of 23.635 which round up to 23.64 and not 23.63. https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/l10n_mx_edi/models/l10n_mx_edi_document.py#L1111 https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/l10n_mx_edi/models/l10n_mx_edi_document.py#L1336 Before this commit https://github.com/odoo/enterprise/commit/39759babddc732a312ec5cd6a60a2f1819abc62c the discount value was being rounded when corrected. It would end up being evaluated to 23.62. To not bring back the issue the fixed by the mentioned commit we round the discount when generating the global invoice cfdi values. Now `importe` will have a value of 23.63 as `descuento` is rounded to 23.62. opw-5023597
This fix helps appointment bookings work correctly when a staff member has a flexible work schedule. It ensures the booking process is clearly identified internally, so related scheduling logic only applies when an appointment is actually being booked.
Original PR description
In the community branch, resource.calendar has a method, `_attendance_intervals_batch`, that can cause a bug if someone attempts to book an appointment with a staff member that has a flexible schedule. But it is used for many things besides booking appointments, and it works correctly for those other things. So, conditional logic was introduced there with a block you should only enter into if an appointment is currently being booked. To facilitate that, a flag signaling that an appointment is being booked, `booking_apt=True`, gets passed down through many of the methods that get called in the process of booking an appointment. Solves ticket 5094795
This change fixes a booking issue where appointments with staff on flexible hours could only be confirmed when the selected time happened to match a hard-coded midday window. Customers can now book valid appointment slots as expected while preserving the existing scheduling behavior used by other business processes.
Original PR description
calendar.resource has a method, `_attendance_interval_batch`, that can cause a bug if someone is trying to book an appointment with a staff with flexible hours.There's an elif block that you enter if…
calendar.resource has a method, `_attendance_interval_batch`, that can cause a bug if someone is trying to book an appointment with a staff with flexible hours.There's an elif block that you enter if the calendar.resource has flexible hours. In that block, we determine how much time is allocated for the appointment. For instance, 1 hour if the appointment is meant to be 1 hour long and the staff still has at least 1 hour left to work that week. Then, a work interval gets centered around 12 noon. 12 noon is hard-coded in. If there's one hour allocated for the appointment, that work interval will always be from 11:30 to 12:30, no matter what appointment time slot was selected. So, unless by lucky coincidence, the person selected an 11:30 appointment, they won't be able to schedule an appointment at all. The hard coding with 12 noon was implemented 4 months ago. It's meant to "solve issues in various apps such as work entry generation, attendance overtime calculation and time off calculations." Since the hard coding around 12 noon serves useful purposes, I didn't remove it. Instead, I added a flag `booking_apt=True` to signal that an appointment is currently being booking. And I added conditional logic so the work interval won't be centered around noon iff an appointment is being booked. I introduced the flag in the appointment.type method `is_appointment_slot_valid`. I originally tried introducing it in a function further up the call stack, but that lead to the flag being true when the current process was getting all possible appointment slots, and it broke that process. It seemed clear from `_is_appointment_slot_valid`'s title and docstring that its sole purpose is to check whether an appointment being booked is at a valid time. Solves ticket 5094795 Description of the issue/feature this PR addresses: It solves ticket 5094795. Current behavior before PR: If you try to book an appointment with a staff with a flexible schedule, and the appointment type's `work_hours_activate` field is true, you'll get a 404 page missing error. (See ticket.) Desired behavior after PR is merged: You will not get a 404 page missing error anymore, and will be able to successfully book an appointment. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents Point of Sale orders from failing when branch users sell products assigned to a parent company with real-time inventory valuation enabled. It ensures staff can complete sales without access errors related to product cost currency information.
Original PR description
Before this commit, if a product was assigned to company A and a user from one of its branches tried to create an order with real-time inventory valuation enabled, the system would raise an access error when reading the product's cost_currency_id field. opw-4969390 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223951
The stock receipt screen now prevents users from editing a lot field that cannot correctly save lot information for lot-tracked products. This avoids a confusing situation where a lot appears selected but validation still fails because the system has not actually assigned it to the stock movement.
Original PR description
### Steps to reproduce: - In the setting enable lots and serial numbers - Create a product tracked by LOT - Create and confirm a receipt for 1 unit of that product - Create a new lot: LOT001 from the…
### Steps to reproduce: - In the setting enable lots and serial numbers - Create a product tracked by LOT - Create and confirm a receipt for 1 unit of that product - Create a new lot: LOT001 from the move in the picking form - Click Validate #### > Invalid operation: you need to provide Lot/Serial numbers of the product ### Cause of the issue: The set method of the `lot_ids` field of the `stock.move` model does nothing for product tracked by lots: https://github.com/odoo/odoo/blob/7a8f9b7fe4dded4cfa140103d51b52e08149cadb/addons/stock/models/stock_move.py#L575-L579 In particular, while the lot appears on the move in the view, none of the move lines refer to it and the transfer can not be validated as indeed no lots are provided to these reservations. ### Fix: The feature of writing `lot_ids` for lots has been introduced in https://github.com/odoo/odoo/commit/4bb4e08066449177f89382718ceadd840ce90d0e https://github.com/odoo/odoo/blob/1c52e2e9e8e00a19e2db00bf70d658496f9a0f29/addons/stock/models/stock_move.py#L596-L600 But this major refactoring can of course not be backported in 18.0. Therefore, it was decided put the field in readonly when its set method is inefficient. opw-5093217 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Active payment providers can no longer have their linked payment journal cleared from the journal settings. This prevents payment failures caused by missing journal information when customers try to pay.
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#225187
Fixed an issue where the rental schedule could hide later rental orders when the same serialized item was rented again. Businesses can now see all relevant rental bookings accurately, improving planning and availability visibility.
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
Point-of-sale orders in Spain that fail to upload to TicketBAI will now be retried automatically instead of blocking later submissions. This helps prevent silent reporting gaps and reduces manual intervention for failed fiscal uploads.
Original PR description
Currently if any PoS order uploads to TicketBAI fail, all future uploads will also silently fail since the chain head was never posted. Steps to reproduce ----- 1. Send a PoS order to TicketBAI have the upload fail 2. Validate another PoS order 3. The upload for the second order is never attempted Cause ----- The first order creates a `l10n_es_tbai_post_document_id` and chain index it is uploaded, but the document's state will remain rejected if the upload is unsuccessful. Any subsequent orders will fail the `_check_can_post()` check since the chain head is not accepted. Solution ----- Create a cron to automatically retry uploading the chain head if it's not posted, and retry any other uploads that were not sent. opw-4669823