Daily updates from Odoo
Navigate
Branch
Wednesday, October 1, 2025
244 changes
10 changes
Enhancements to existing features
The website generator now checks whether a provided website URL can be reached before starting the scraping process. This helps users catch typos or inaccessible pages earlier, saving time and providing clearer feedback.
Original PR description
This commit checks that the URL is reachable before making the scraper request. The goal is to help prevent clients from requesting pages that may have a typo or are not accessible. This reduces time wasting and gives a much clearer interface. <img width="967" height="604" alt="image" src="https://github.com/user-attachments/assets/70810b13-65bd-43a3-9fc1-125867290a9b" /> <img width="1690" height="961" alt="image" src="https://github.com/user-attachments/assets/df347756-85b0-451b-9cab-47d20097ed8b" /> <img width="976" height="751" alt="image" src="https://github.com/user-attachments/assets/bcea820b-ebe3-4b0f-875c-2b8f4fdf0404" />
Resolved issues and error corrections
Free products added through sales loyalty rewards now use the reward description as the order line name instead of the product’s default name. This makes sales orders clearer and keeps the behavior consistent with point of sale rewards when teams customize reward descriptions.
Original PR description
Currently, the reward's product name is used as the SOL name for the free product, which can be confusing. **To reproduce this issue:** 1) Install the sale_loyalty module. 2) Create a loyalty program…
Currently, the reward's product name is used as the SOL name for the free product, which can be confusing. **To reproduce this issue:** 1) Install the sale_loyalty module. 2) Create a loyalty program that grants a free product. 3) Manually update the reward's description. 4) Create a SO with a SOL containing that product 5) Apply the reward and observe the behavior. **Issue / Cause:** - The free product's description is taken from the reward product's name instead of the manually updated description. - This is incorrect because, in the point of sale, the name is taken from the reward's `discount_line_product_id` rather than the `reward_product_ids`. https://github.com/odoo/odoo/blob/0abdcd9ef6ad3fc932dc0eb46d8aa973b00c34c2/addons/pos_loyalty/static/src/overrides/models/pos_order.js#L1162 **Solution:** To resolve this inconsistent behavior, the free product name in the sale order line will now be taken from discount_line_product_id. opw-4982774 Forward-Port-Of: odoo/odoo#229152 Forward-Port-Of: odoo/odoo#223755
The cohort report export button is now disabled when there is no data to export. This prevents users from triggering an error on empty reports, such as Helpdesk Ticket Analysis without records, and provides a smoother reporting experience.
Original PR description
Currently, an error occurs when user tries to export data on cohort view with no data. Steps to replicate: - Install `helpdesk` (without demo data). - Go to `Helpdesk > reporting > Ticket Analysis` and go to cohort view. - Click download and error will occur. - If error doesnt occur, click on `Measure > Count`, and click Download again. Error: `IndexError: list index out of range` Cause: - The export button remained enabled even when no data available, this caused the export to be called without any data that caused the `Indexerror` at [1]. Solution: - Disabled the export button when no data in cohort view. [1]: https://github.com/odoo/enterprise/blob/475a802aa3e748a905be83c0f6408f8c20f03905/web_cohort/controllers/main.py#L30 sentry-6831823426 Forward-Port-Of: odoo/enterprise#93050
Customers viewing an online order that includes a manufactured product will now see the manufacturing date only once. This keeps the order portal cleaner and avoids confusion caused by repeated information.
Original PR description
**Steps to reproduce:** 1.Install `website_sale` and `sale_mrp`. 2.In settings, enable `multi-route` and `unarchive` the Replenish MTO route. 3.Create a product with routes -> `Replenish MTO` and…
**Steps to reproduce:** 1.Install `website_sale` and `sale_mrp`. 2.In settings, enable `multi-route` and `unarchive` the Replenish MTO route. 3.Create a product with routes -> `Replenish MTO` and `Manufacturing` then publish it on the website. 4.Buy the product from the website and make the payment. 5.Go to My Account → Your Orders → Open your sale order. 6.In the Manufacturing section, the date appears twice. **Issue-** <img width="604" height="186" alt="image" src="https://github.com/user-attachments/assets/e4164564-8555-4005-8282-20e6f5de7e55" /> - Date found twice in Portal View of sale order **Cause-** https://github.com/odoo/odoo/blob/097c04156517bd97a2789bde22ffd0c69c0bf6bf/addons/sale_mrp/views/sale_portal_templates.xml#L18-L27 - Here using same field two time one it with condition and other is without condition so in some case when condition satisfied then same field are coming twice **Solution-** - Remove Conditional field because no meaning of using same field inside and outside of the condition **opw - 5096009** Forward-Port-Of: odoo/odoo#227997
Saving a view or editing a report with an attribute tag missing its name no longer triggers an unexpected error. The system now skips these incomplete attributes safely, improving stability for users working with views or Web Studio reports.
Original PR description
Currently, an error occurs when user tries to save a view with an attribute node without name. **Steps to replicate:** - Initialize a DB and open Views. - Create a new view and fill in random values…
Currently, an error occurs when user tries to save a view with an attribute node without name.
**Steps to replicate:**
- Initialize a DB and open Views.
- Create a new view and fill in random values for name and give a View Type.
- In the Architecture give value as `<attribute></attribute>`.
- Save and you will get the error.
(Same error can also be produced with Web Studio report editor.)
**Error:**
`AttributeError: 'NoneType' object has no attribute 'endswith'`
**Cause:**
- The error occurred because we received **key** as `None` at [1], as it was called from an attribute node with no name [2].
- In `saas-18.2`, we only checked if `node.get('name') not in TRANSLATED_ATTRS`. Since `node.get('name')` was `None` and `None` was not included in the `TRANSLATED_ATTRS` list, no error occurred.
**Solution:**
- Added a conditional check, so that attributes with no name skip the function call.
[1]: https://github.com/odoo/odoo/blob/f254da2253e7ce9426e51112b513fa9e6a474ce4/odoo/tools/translate.py#L83
[2]: https://github.com/odoo/odoo/blob/f254da2253e7ce9426e51112b513fa9e6a474ce4/odoo/tools/translate.py#L190
[3]: https://github.com/odoo/odoo/blob/0b700ec3c08ecd9c6f1597f9d10f6c1eee06bcee/odoo/tools/translate.py#L255
sentry-6877030439
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#227221The stock receipt form now prevents users from entering lot information in a field that cannot correctly apply it for products tracked by lot. This avoids validation errors where a lot appears to be selected but is not actually assigned to the transfer.
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 Forward-Port-Of: odoo/odoo#228840
This fixes a Razorpay payment issue where accounts configured with both standard keys and OAuth could trigger failed mobile payments. Odoo now avoids mixing authentication methods, reducing 403 errors during customer checkout on iOS and Android.
Original PR description
In a specific context, Razorpay rejects connections using both Key ID/Secret and an access token simultaneously. To reproduce, it's require a real production Razorpay account since Oauth is not available in test mode. Step to reproduce: - Configure Key ID/Secret and connect via OAuth on the Razorpay payment provider. - On iOS/Android, making a payment on the website triggers a "403 Forbidden" error because Razorpay redirect to `/payment/razorpay/return` and the signature from Razorpay not correspond to the expected signature computed with the Key Secret. This fix prioritizes call with Key ID/Secret over token authentication. if not configured. opw-5100194 opw-4989944 opw-5039880
Manufacturing reports now include estimated employee costs correctly in cost and production analysis. This helps businesses get more accurate visibility into expected production costs and compare operations more reliably.
Original PR description
Make sure that operations with estimated costs are correctly computed in the Cost Analysis Report and the Production Analysis Report. task 4896715
Swedish payment export files now identify bankgiro accounts with the correct account type instead of treating them as standard bank accounts. This helps Swedish credit transfer files meet banking requirements and reduces rejected or incorrect payments.
Original PR description
Issue: The only possible value for the bank account type is "BBAN". For a 'bankgiro' account it should be "BGNR". Solution: Input "BGNR" in the XML if the bank account type is 'bankgiro'. opw-5063368 Forward-Port-Of: odoo/enterprise#95467
Belgian POS users can now sell products and close sessions even when multiple employees are clocked in on the same register. This prevents unexpected errors that could interrupt sales or end-of-day closing.
Original PR description
- Fix traceback when trying to sell a product with multiple employees clocked in on the same POS. - Fix traceback when trying to close a session with multiple employees clocked in. task-id: 4902090 Forward-Port-Of: odoo/enterprise#93942 Forward-Port-Of: odoo/enterprise#93273
16 changes
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
This update corrects an internal sales and manufacturing test so it reflects that kits can be invoiced before delivery when configured to invoice ordered quantities. It helps keep automated checks aligned with expected business behavior and reduces the risk of false build failures.
Original PR description
This change updates the test_sell_kit_invoice_before_delivery test to ensure that kit components and the kit product itself use an invoicing policy of Ordered Quantities rather than the default Delivered Quantities. build_error-232796 Forward-Port-Of: odoo/odoo#227870
The website shop now handles invalid category values in product page URLs more gracefully. This prevents a server error when someone opens or tampers with a link containing malformed category information, improving reliability for visitors.
Original PR description
Currently, an error occurs when the `category` is received as a `string` and the code tries to evaluate `int(category)`. **Steps to reproduce:** - Install the `website_sale` module. - Open a product page in the website with an `invalid category` parameter, for example: `http://localhost:8069/shop/warranty-39?category=1;` **Error:** `ValueError: invalid literal for int() with base 10: '1;'` **Root Cause:** At [1], the code directly calls `int(category)` without validating the input. When the parameter contains `non-numeric` characters, Python raises an `error`. **Fix:** This commit ensures raising a `ValidationError`, improving the `error message` clarity, when users manually input `invalid or tampered` category values in the `URL`. [1]: https://github.com/odoo/odoo/blob/d32f98dd199f80d2b0031bd52a6ff74411c3e7e0/addons/website_sale/controllers/main.py#L1827 sentry-6658317828
The chatter follower menu now stays open when a user removes a follower, making it easier to remove several followers in one session. The related edit subscription action now closes the menu consistently, reducing confusion in day-to-day record collaboration.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ Removing multiple followers from the chatter is cumbersome because the followers dropdown closes immediately after each removal. Additionally, clicking 'Edit Subscription' next to 'Unfollow' did not close the dropdown, which was inconsistent with expected behavior. **Current behavior before PR:** --------------------------------- - Removing a follower from the chatter closes the followers dropdown immediately - Clicking 'Edit Subscription' next to 'Unfollow' leaves the dropdown open **Desired behavior after PR is merged:** ----------------------------------------- - The followers dropdown remains open after removing a follower, allowing multiple removals without interruption - Clicking 'Edit Subscription' next to 'Unfollow' closes the dropdown as expected **Task:** 4943867
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
This fixes a crash that could happen in Discuss calls when an update arrived for a session that had already been removed. It improves reliability for users by safely ignoring outdated session updates instead of interrupting the experience.
Original PR description
Before this commit, since a regression introduced in https://github.com/odoo/odoo/pull/228601 A traceback could occur when updating a session that does not exist. For example if the event is received after the session is removed. Forward-Port-Of: odoo/odoo#229166 Forward-Port-Of: odoo/odoo#229073
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 an issue where packaging details could be missing on products with a single variant. It ensures product packaging information is correctly applied, helping avoid incorrect or incomplete product setup in daily operations.
Original PR description
e158730ba16e898a13dd9a98ed96fa30fa95ab6f recently fixed a situation where one-variant products had duplicated packagings. In the aforementioned commit, we concluded that the logic to write (again) the templates values for variant-stored fields was useless because already applied to the generated variants. Nevertheless, while trying to remove in master this logic, we noticed that those varlues are only applied to variants of templates having at least one attribute line, whose creation will trigger the variants creation. This commit therefore partially reverts the previous commit, bringing back the first solution that is still the best approach in the end. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229080
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
This fix prevents manufacturing planning from failing when work orders have extremely small duration values. It ensures schedules can still be calculated reliably, avoiding errors that could block production planning.
Original PR description
Operation & Workorder duration is a float with 2 decimal digits to be expressed in minutes, meaning minimal duration is 1sec. However one can encounter numbers like 0.001, 0.00001, ... This can lead to : AttributeError: 'NoneType' object has no attribute 'astimezone' in function _get_first_available_slot task: 5090338 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227253
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
A website sales test was updated so it prepares price lists before checking GeoIP-based cart pricing. This prevents false test failures in databases without demo data, improving reliability without changing customer-facing behavior.
Original PR description
Versions -------- - saas-18.3+ Steps ----- 1. Have a database without demo data; 2. run `test_cart_new_pricelist_from_geoip`. Issue ----- Test fails, due to the order not having a pricelist. Cause ----- Pricelists aren't enabled by default without demo data. Solution -------- Call `self._enable_pricelists()` at the start of the test. runbot-232989
This fixes an issue where highlighted design effects in website page templates could be carried into newly created pages in the wrong internal format. Business users creating new website pages from templates should now see highlights render correctly and consistently.
Original PR description
Starting from [1], the code from the "Snippets Preview" and the "New Page Templates Preview" was adapted to be able to build a highlight using its simplified format when provided in XML. The goal of this PR is to fix the new page DOM when a template with highlights is selected. The DOM will be simply cloned and used for the created page, so we need to reset the inner highlights to their minimal format. [1]: https://github.com/odoo/odoo/commit/4a29fa66003ce1f42a7011bc56fc019f34a887f5 task-4215788 Forward-Port-Of: odoo/odoo#185820
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
Free products added through loyalty rewards now use the reward description set by the business instead of the product's default name. This makes sale orders clearer and keeps loyalty behavior consistent with point-of-sale flows.
Original PR description
Currently, the reward's product name is used as the SOL name for the free product, which can be confusing. **To reproduce this issue:** 1) Install the sale_loyalty module. 2) Create a loyalty program…
Currently, the reward's product name is used as the SOL name for the free product, which can be confusing. **To reproduce this issue:** 1) Install the sale_loyalty module. 2) Create a loyalty program that grants a free product. 3) Manually update the reward's description. 4) Create a SO with a SOL containing that product 5) Apply the reward and observe the behavior. **Issue / Cause:** - The free product's description is taken from the reward product's name instead of the manually updated description. - This is incorrect because, in the point of sale, the name is taken from the reward's `discount_line_product_id` rather than the `reward_product_ids`. https://github.com/odoo/odoo/blob/0abdcd9ef6ad3fc932dc0eb46d8aa973b00c34c2/addons/pos_loyalty/static/src/overrides/models/pos_order.js#L1162 **Solution:** To resolve this inconsistent behavior, the free product name in the sale order line will now be taken from discount_line_product_id. opw-4982774 Forward-Port-Of: odoo/odoo#229152 Forward-Port-Of: odoo/odoo#223755
4 changes
Resolved issues and error corrections
The cohort reporting view now disables the download option when there is no data to export. This prevents users from encountering an error in Helpdesk ticket analysis and makes empty reports behave more predictably.
Original PR description
Currently, an error occurs when user tries to export data on cohort view with no data. Steps to replicate: - Install `helpdesk` (without demo data). - Go to `Helpdesk > reporting > Ticket Analysis` and go to cohort view. - Click download and error will occur. - If error doesnt occur, click on `Measure > Count`, and click Download again. Error: `IndexError: list index out of range` Cause: - The export button remained enabled even when no data available, this caused the export to be called without any data that caused the `Indexerror` at [1]. Solution: - Disabled the export button when no data in cohort view. [1]: https://github.com/odoo/enterprise/blob/475a802aa3e748a905be83c0f6408f8c20f03905/web_cohort/controllers/main.py#L30 sentry-6831823426 Forward-Port-Of: odoo/enterprise#93050
Customer statements sent by email from a child contact now avoid generating empty PDF attachments. The Customer Statement button is also hidden when there are no transactions or no amount due, preventing users from sending irrelevant statements.
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#93162
This fix makes comments in Knowledge articles appear consistently after editing, reloading, or switching between locked read-only articles. It also prevents crashes when users try to add comments inside code blocks, improving reliability for teams collaborating in Knowledge.
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
The Belgian point of sale fiscal device integration now distinguishes warnings from real errors when receiving responses from the connected IoT device. Warnings will show as notifications instead of incorrectly blocking or treating them as failures, helping cashiers continue normal operations when no actual error occurred.
Original PR description
Before this commit, all errors returned by the iot after a call to the blackbox were considered as errors. Actually, the errors are only the ones that do not start with 0 (no error) or 1 (warning). This commit changes the behaviour when handling warning. We now show a notification.
33 changes
New functionality added to Odoo
Adds support for Biteship, a logistics aggregator in Indonesia, so businesses can compare shipping rates, create or cancel delivery orders, access tracking links, and generate shipping labels directly in Odoo. This helps streamline fulfillment operations for companies shipping through Indonesian carriers.
Original PR description
Biteship is a third-party logistics aggregator that connects users to various logistic company in Indonesia - Fetch shipment rate - Create and cancel delivery order - Retrieve tracking link - Provide shipping label as a custom report Task ID : [4641931](https://www.odoo.com/odoo/project.task/4641931)
The Sign app now lets internal users place a read-only company stamp on documents. This makes it easier to include official company details such as name, address, phone, VAT number, and logo for a more professional document presentation.
Original PR description
Before: * There was no way for users to add a company stamp to documents in the Sign app. After: * A new `Stamp` item is now available in the Sign app. * Internal users can drag and drop the stamp item into a document, which contains company details like the company’s name, address, phone number, VAT number and logo. * The stamp is styled as an image and is read-only to keep it consistent. Impact: * Makes it simple to include official company information in signed documents. * Helps ensure a more polished and professional look. task-4819989 --- 📎 Stamp Example: Attached below is a sample image of how the stamp appears in a signed document. <img width="500" height="300" alt="image" src="https://github.com/user-attachments/assets/5e65e78b-0e68-40e0-8774-a492e405530c" />
Enhancements to existing features
This update improves how Odoo handles record identifiers so empty or invalid values are not mistaken for real records. It helps prevent errors and inconsistent results across accounting reports, expenses, manufacturing, subscriptions, and Studio reports.
Original PR description
https://github.com/odoo/odoo/pull/227477
The Documents app now displays the full set of available model labels in the details panel instead of leaving users to infer hidden options. This makes selection clearer because the list is short, fixed, and not searchable.
Original PR description
As the list is static and there are only a few and searching for more is not supported, this enables to show all labels so that users don't have to guess what is available or not. Task-5075200 Forward-Port-Of: odoo/enterprise#95483 Forward-Port-Of: odoo/enterprise#94180
Employee version records now track changes to most business-relevant HR fields across payroll, contracts, salary, holidays, attendance, signing, accounting, and country-specific payroll areas. This improves transparency by making it easier to review when important employee-related information was changed and supports stronger auditability.
Original PR description
Most fields in hr.version represent business-relevant employee data that should be tracked to ensure a complete audit trail. This commit adds `tracking=True` by default on hr.version fields across community and enterprise modules. task-5022109 Forward-Port-Of: odoo/enterprise#95625 Forward-Port-Of: odoo/enterprise#92601
The bank reconciliation kanban quick-create process has been simplified so entries are saved as soon as the required information is available. This should make reconciliation workflows smoother for accounting users while reducing custom maintenance behind the scenes.
Original PR description
Task~5072955
The AI button hover effect has been refined so the visual logo treatment is more consistent. Other related button hover states were adjusted to better highlight the intended action, making the interface feel clearer and more polished.
Original PR description
This PR harmonizes the AI button hover by using the logo as the button's ::before pseudo-element. It also modifies the hover state of other buttons to emphasize the desired element. task-5093189 PR-commu: https://github.com/odoo/odoo/pull/227632 Forward-Port-Of: odoo/enterprise#94944
The website generator now accounts for changes introduced in Odoo 19.0 eCommerce building blocks. This helps ensure generated websites use the right scraper behavior for the Odoo version, reducing compatibility issues when creating or updating online stores.
Original PR description
Corresponding IAP PR: https://github.com/odoo/iap-apps/pull/1196 Forward-Port-Of: odoo/enterprise#94389
Rental-related tests were adjusted to reflect a change in how delivery dates are updated behind the scenes. This helps ensure rental workflows remain correctly validated after backend date behavior changed, without altering the customer-facing rental process.
Original PR description
The inverse method set on `scheduled_date` in `stock.picking` has been removed and changed to onchange in order to fix some bugs with having a compute-inverse. For example, on updating one stock move date, it updates every move date. Which is incorrect and inconvenient. Since onchange is only triggered through UI, changing `scheduled_date` from the backend doesn't trigger the onchange. Therefore, the tests were edited to change the move dates manually. Task: 4687135
This update introduces a dedicated form view for VoIP calls, making call details easier to review and manage. It also includes several related improvements and fixes across accounting, AI, point of sale, spreadsheets, and subscriptions to improve daily workflows and reliability.
VoIP calls can now be recorded directly in the user's browser as an early proof of concept. This helps explore easier call capture without server-side storage, with recordings downloaded locally after the call ends.
Creating repair orders is now much faster when the system has a very large number of quality rules. The process uses the database more efficiently and avoids overly large queries, reducing delays for businesses with heavy quality control data.
Original PR description
Description ----------- Creating a repair creates new `quality.check` based on `quality. point`s. When you have many matching points to explore, the `filtered_domain` can be pretty slow when…
Description ----------- Creating a repair creates new `quality.check` based on `quality. point`s. When you have many matching points to explore, the `filtered_domain` can be pretty slow when processing linear the records to compute the intersection between the all points and the points that should be associated with the repair. This commit rewrites `_create_quality_checks_for_repair` to use a `search` instead if necessary, to offload the intersection search in the database. We also split the ids to not inject a large list of ids in the query. Benchmark --------- For a database that will have 500k `quality.point` that satisfies the domain of `quality.point._get_domain`, the invocation of `_create_quality_checks_for_repair` for creating a Repair takes (excluding the `create` call time): | | Before | After | |---------|------------------|-------| | Timings | Timeout (15+min) | 1 min | Reference --------- opw-4980036 Forward-Port-Of: odoo/enterprise#95700 Forward-Port-Of: odoo/enterprise#91729
IoT Boxes now receive a clear unauthorized error when trying to download drivers without a matching database record. This helps teams identify setup or registration issues faster instead of seeing an unclear empty response.
Original PR description
When an iot box tries to download drivers from the database, but the db doesn't have a record corresponding to the IoT Box, the IoT Box receives an empty string, making it hard to debug why it couldn't download handlers. We now raise an unauthorized error to make it clearer. Forward-Port-Of: odoo/enterprise#94311 Forward-Port-Of: odoo/enterprise#93813
Resolved issues and error corrections
Shiprocket Cash On Delivery orders now correctly include coupon discount amounts when sending shipment details. This helps ensure the amount collected from customers matches the discounted order total, including taxes.
Original PR description
Issue ----- When using Shiprocket with the "Cash On Delivery", the request sent to the Shiprocket API doesn't contain the amounts discounted by coupons. Steps to reproduce ----- - Set an Indian…
Issue
-----
When using Shiprocket with the "Cash On Delivery", the request sent to the Shiprocket API doesn't contain the amounts discounted by coupons.
Steps to reproduce
-----
- Set an Indian company up (with valid address and some dummy mail & phone)
- Create a customer "IN Cust" (with valid address and some dummy mail & phone)
- Create a product "IN Prod"
- Sale price: 1000 INR
- Weight: 100g
- Set some reference, eg "INPROD"
- Create a Shiprocket delivery method
- Payment Method: COD
- Set some "Shiprocket Channel"
- Enable Debug requests
- In settings, enable "Promotions, Loyalty & Gift Card"
- Go to Sales > Products > Discount & Loyalty
- Create a new program
- Name: 50% off
- Program Type: Coupons
- Change the existing reward to 50% discount on order
- Generate some coupon
- Copy the code of the generated coupon
- Create a SO our product and customer
- Use the coupon code & apply the 50% discount
- Add shipping
- Shiprocket COD
- Get rate
- Confirm the SO
- Go to the picking & validate it
- Open logs (Settings/Technical/Database Structure/Logging)
- Open the "shiprocket_request_external/shipments/create/forward-shipment" log
--> total_discount is 0
Cause
-----
The problem comes from
https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L301
There are 2 issues here.
The first and most important one is how we find the discount lines.
https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L320
Discounts from coupons don't use the `sale_discount_product_id`. We can use the `_can_be_invoiced_alone` function to find both regular and loyalty discounts
https://github.com/odoo/odoo/blob/ee63fe7863dfa0083674dc927c1aa67c9e36c481/addons/sale/models/sale_order_line.py#L1033-L1041
def _can_be_invoiced_alone(self):
""" Whether a given line is meaningful to invoice alone.
It is generally meaningless/confusing or even wrong to invoice some specific SOlines
(delivery, discounts, rewards, ...) without others, unless they are the only left to invoice
in the SO.
"""
self.ensure_one()
return self.product_id.id != self.company_id.sale_discount_product_id.id
https://github.com/odoo/odoo/blob/ee63fe7863dfa0083674dc927c1aa67c9e36c481/addons/sale_loyalty/models/sale_order_line.py#L50-L51
def _can_be_invoiced_alone(self):
return super()._can_be_invoiced_alone() and not self.is_reward_line
We just have to be careful not to accidentally include delivery fees because of
https://github.com/odoo/odoo/blob/ee63fe7863dfa0083674dc927c1aa67c9e36c481/addons/delivery/models/sale_order_line.py#L18-L19
def _can_be_invoiced_alone(self):
return super()._can_be_invoiced_alone() and not self.is_delivery
The second issue is that we use the untaxed discount amount.
https://github.com/odoo/enterprise/blob/a971f55e736f9645eda137fd6dcb574483886483/delivery_shiprocket/models/shiprocket_request.py#L321
This leads to an incoherent total amount, since the tax is computed on the products' full prices. We should instead be forwarding the total discount value (with tax included to offset the taxes applied on the full product price).
-----
Community PR:
https://github.com/odoo/odoo/pull/223517
Ticket:
opw-4755357
Forward-Port-Of: odoo/enterprise#95563
Forward-Port-Of: odoo/enterprise#92310This fix ensures Swedish non-EU purchase VAT with a non-zero amount is correctly included as deductible input VAT. It improves the accuracy of Swedish tax reports and restores related automated checks.
Original PR description
The taxes "EX G" (VAT Purchase of goods outside EU) with a non-zero amount should have the tag se_48 (Input VAT to be deducted). This PR fixes the tests that were broken because of it: odoo/odoo#227513 opw-4916405 Forward-Port-Of: odoo/enterprise#95751
The point of sale now waits for blackbox discount processing to finish before allowing payment. This prevents outdated payment amounts from being sent to a terminal, reducing cashier confusion and payment errors.
Original PR description
Before this commit, if a discount was applied with the blackbox, it was applied after communication with blackbox which could be slow. If the user was clicking payment before this disound was applied and had only one payment method, a payment line with the old amount was added which could lead to confusion and errors when this payment line was sent to a terminal. This is fixed by waiting for the discount to be applied before being able to click on payment. Community PR: https://github.com/odoo/odoo/pull/221020 Forward-Port-Of: odoo/enterprise#93809 Forward-Port-Of: odoo/enterprise#91256
Helpdesk users can now open closed-ticket views and use closed-date filters without triggering an error. This keeps ticket reporting and follow-up workflows accessible when teams filter recent closed tickets.
Original PR description
Steps to reproduce: - 1. Install the helpdesk module. 2. Navigate to the Helpdesk Overview dashboard. 3. On any team card (e.g., VIP Support), click the 'Tickets Closed'. 4. (Alternative): Go to the 'All Tickets' list view, open the search filters, and select a 'Closed On' date filter like 'Last 7 Days'. Issue: - Clicking the 'Tickets Closed' button or applying a 'Closed On' date filter results in a server traceback (ValueError). Cause: - The search filters used an invalid date syntax with multiple operators like `today -7d + 1d` (introduced in commit https://github.com/odoo/enterprise/commit/3db2ad2424f5d40b51bedfba4475fa6b0602c955). Fix: - Corrected the syntax like `today -7d +1d`. task-5069003 Forward-Port-Of: odoo/enterprise#94048
The cohort report export button is now disabled when there is no data to export. This prevents users from hitting an error when downloading empty Helpdesk ticket analysis reports and makes the reporting experience smoother.
Original PR description
Currently, an error occurs when user tries to export data on cohort view with no data. Steps to replicate: - Install `helpdesk` (without demo data). - Go to `Helpdesk > reporting > Ticket Analysis` and go to cohort view. - Click download and error will occur. - If error doesnt occur, click on `Measure > Count`, and click Download again. Error: `IndexError: list index out of range` Cause: - The export button remained enabled even when no data available, this caused the export to be called without any data that caused the `Indexerror` at [1]. Solution: - Disabled the export button when no data in cohort view. [1]: https://github.com/odoo/enterprise/blob/475a802aa3e748a905be83c0f6408f8c20f03905/web_cohort/controllers/main.py#L30 sentry-6831823426 Forward-Port-Of: odoo/enterprise#93050
Users with viewer access can now mark or unmark documents as favorites using the keyboard shortcut without encountering an access error. This makes the Documents experience more consistent between shortcut-based and manual favoriting.
Original PR description
steps to reproduce =================== - Select a document where you have viewer permission. - Try to toggle the favorite through a hotkey. - Access Error when toggling favorite. Technical =========== - Adapted the `toggle_favorited` to handle multiple records. After this commit ================== - This commit handles the accessError for shortcut flow. As in 18.3 we already have documents_favorite widget https://github.com/odoo/enterprise/pull/82639 which will work for manually favoriting the document, but it is not handling the shortcut flow. Task-4910326 Forward-Port-Of: odoo/enterprise#89928
Bank transactions from a company branch can now be reconciled with payments from the main company or related branches when they share the same end-to-end payment reference. This prevents valid payments from being left unreconciled in multi-branch company setups.
Original PR description
…o end uuid The aim of this commit is handling branches cases with reconciliation via the end to end uuid. Before this commit, a bank transaction from a company branch couldn't be reconciled with a payment from the main company. In some situation this case could happen. Now payments and bank transactions are reconciliable even if both are from another company. It works only for companies with the same main company, branches which are sisters or parent-children relation. task-5081684 Forward-Port-Of: odoo/enterprise#94592
Brazilian electronic invoicing now better detects failed submissions even when the tax service response does not include the usual error field. This prevents rejected invoices from being incorrectly treated as successfully processed, improving reliability for Brazilian fiscal workflows.
Original PR description
Avalara typically returns errors by including an "error" key, but this doesn't always happen. In case of a "302" code response we were erronously considering EDI to have succeeded. To fix this, we implement an additional error code check using codes from the official specification [1]. It's tempting to think that every code in the [100, 199] range is a successful one, but 142 is a rejection code. [1] https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=J+I+v4eN00E%3D opw-4766828
This update makes a Planning app test more reliable when demo data is present. It clears existing records before counting them, preventing false test failures and helping maintain stable quality checks.
Original PR description
Reason: - In the test case we check for record count, so we get the count of all the demo data installed too. Fix: - Remove all the records before hand to check for the count. https://runbot.odoo.com/odoo/runbot.build.error/231599 runbot-231599 Forward-Port-Of: odoo/enterprise#95736
This fixes an issue in Sales Commission reporting that could prevent grouped report data from being formatted properly. It helps ensure commission achievement and commission reports display reliably for users reviewing sales performance.
Original PR description
runbot-89585061 Forward-Port-Of: odoo/enterprise#95263
Field service tasks now price service lines using the customer’s assigned pricelist instead of the product’s default price. This ensures customers are billed according to their agreed pricing when tasks are validated.
Original PR description
Before this commit, the service line on the sale order ignored the customer’s pricelist and used the product’s default price. Steps to reproduce: - Assign a fixed-price pricelist to a customer. - Create an FSM task for them and add a timesheet. - Validate the task and check the service line price. After this commit, the service line correctly reflects the price from the assigned pricelist. task-4830183 Forward-Port-Of: odoo/enterprise#95744 Forward-Port-Of: odoo/enterprise#88039
A Turkish payroll employee field is now only visible to authorized HR/payroll users. This prevents non-HR internal users from encountering access errors when viewing employee public profile data.
Original PR description
The test test_employee_fields_groups crashed with: AccessError: The fields “l10n_tr_is_net_to_gross”, which you are trying to read, are not available for employee public profiles. This field exist without HR group restriction as a result, a non-HR internal user calling .read([]) triggered the AccessError. This commit adds groups="hr.group_hr_user" to this field so it is only accessible to HR users, resolving the error. [RB-231736](https://runbot.odoo.com/odoo/error/231736) Forward-Port-Of: odoo/enterprise#94796
The timesheet grid now avoids making invalid requests when a row has a project but no task. This prevents errors in timesheet planning views and helps users continue working without interruptions.
Original PR description
If there are rows in the grid view with a project but no task, we call `get_planned_and_worked_hours` on a `False` id, which is not allowed since https://github.com/odoo/odoo/pull/227477
Swedish payment export files now identify Bankgiro accounts with the correct account type instead of treating them as standard BBAN accounts. This helps ensure bank payment files are accepted and processed correctly for companies using Bankgiro accounts.
Original PR description
Issue: The only possible value for the bank account type is "BBAN". For a 'bankgiro' account it should be "BGNR". Solution: Input "BGNR" in the XML if the bank account type is 'bankgiro'. opw-5063368 Forward-Port-Of: odoo/enterprise#95467
Swedish Bankgiro and Plusgiro accounts are now handled correctly when generating SEPA payment files and Peppol BIS 3 invoices. This prevents missing bank details in payment files and ensures invoice XML includes the required bank identifier while leaving other bank accounts unchanged.
Original PR description
Bankgiro and Plusgiro accounts in Sweden normally do not have a BIC. However, for Peppol BIS 3 invoices, a BIC tag is required in the XML. The existing _skip_CdtrAgt logic prevents _get_CdtrAgt from being called when no BIC is set, causing the clearing_number to be missing in SEPA payment files for Bankgiro and Plusgiro accounts. This commit introduces overrides for SE-specific account types: _get_cleaned_bic_code: Returns 'SE:Bankgiro' or 'SE:Plusgiro' for Swedish Bankgiro and Plusgiro accounts, ensuring a BIC is present for the invoice XML. _skip_CdtrAgt: Returns False for Bankgiro and Plusgiro accounts to ensure _get_CdtrAgt is called, including the clearing number in the payment file. This guarantees that SEPA payment files and Peppol BIS 3 invoices for Sweden are generated correctly while preserving standard behavior for other banks and countries. Forward-Port-Of: odoo/enterprise#95910
The OSS report can now open correctly when a fiscal position uses a country group instead of a directly selected country. This helps businesses handle VAT reporting setups such as mainland Spain excluding the Canary Islands without report access errors.
Original PR description
To be able to deal with Spain with Canary Islands and mainland, we have a country group that is Mainland Spain VAT, with Spain minus several states (Canary basically). People want to be able to use it for OSS. But currently, if you have an entry with a tax with a fp with this country group (and no country), you can't open your OSS Report. So take the countries of the country group if there is none in the fiscal position. Forward-Port-Of: odoo/enterprise#95795
The Sign app’s “Try a sample contract” button now displays with the correct color in dark mode. This makes the empty-screen action easier to read and keeps the interface visually consistent for users.
Original PR description
The "Try a sample contract" button was implemented with the `text-white` class, which is inverted to black in dark mode, making it inconsistent and not very readable. This commit removes that class. task-5129727 __________ | Before | After | |--------|--------| | <img width="488" height="351" alt="Screenshot 2025-10-01 at 13 18 02" src="https://github.com/user-attachments/assets/c5d00f6a-a086-48e2-b0f9-62828e8801e7" /> | <img width="414" height="350" alt="Screenshot 2025-10-01 at 13 17 39" src="https://github.com/user-attachments/assets/f8fc9707-f520-4c6f-838a-59ee77ae9cb9" /> |
This fixes Engineering Change Orders so very small bill of materials quantity changes use the product unit of measure precision instead of rounding to two decimals. Businesses using high-precision units can now track and apply component changes such as 0.0003 accurately.
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#95180Features or functions removed from Odoo
Odoo is deprecating the paid Carvajal integration for Colombian electronic invoicing because a free Odoo-managed alternative is now available. Businesses using Colombian localization should plan to move to the built-in DIAN flow to avoid relying on the retired provider.
Original PR description
Now that we have our own free alternative for Carvajal, the time has come to put it to rest. task: 4418763
Code cleanup and technical improvements
The point of sale payment terminal setup has been reorganized to use a shared registry instead of a POS-only mechanism. This does not change current behavior, but it prepares Ingenico, SIX, Worldline, and Tyro payment terminals for reuse in future sales flows such as self-ordering.
Original PR description
* = {iot_ingenico, iot_six, iot_worldline, tyro}
Before this commit, payment terminal JS classes were registered using the `register_payment_method` function in the POS, which added them to an internal map of classes. Then this map was used to instantiate the correct JS class for each payment terminal.
After this commit, we use the `registry` from the `web` module to do the same thing. This has the advantage of not being locked only to the `pos_store` class, meaning in the future we will be able to use this registry in `pos_self_order` also. At this stage though there is no change in functionality.
task-488272620 changes
Enhancements to existing features
This update makes it easier for custom Odoo modules to adapt how product stock valuation-related values are calculated. It mainly supports future customization needs without changing day-to-day user workflows.
Original PR description
FWP of https://github.com/odoo/odoo/pull/160201 cc @pfertyk @svs-odoo --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222410
Resolved issues and error corrections
Invoices with early payment discounts are no longer treated as fully paid when the customer pays the discounted amount after the discount deadline. This prevents underpaid invoices from being closed automatically and keeps the remaining balance visible for follow-up.
Original PR description
Purpose: With [commit], a bank line with an amount slightly less than the invoice (within 3% tolerance) marks the invoice as fully reconciled. However, this can be confusing with early payment discounts, as an invoice paid after the discount period and even with the discounted amount may also appear fully reconciled due to the 3% tolerance. After this commit: In case of early payment discount and payment after the discount, 3% tolerance is not applied, so If discounted amount is paid then invoice is only partially reconciled. task-5090274 [commit]: https://github.com/odoo/enterprise/commit/9bea3f2c517e77fdb822eb53b9648e9fc5478dac
The customer order portal no longer shows the same manufacturing date twice for made-to-order manufactured products. This keeps the order details clearer for customers and avoids confusion when they review purchases online.
Original PR description
**Steps to reproduce:** 1.Install `website_sale` and `sale_mrp`. 2.In settings, enable `multi-route` and `unarchive` the Replenish MTO route. 3.Create a product with routes -> `Replenish MTO` and…
**Steps to reproduce:** 1.Install `website_sale` and `sale_mrp`. 2.In settings, enable `multi-route` and `unarchive` the Replenish MTO route. 3.Create a product with routes -> `Replenish MTO` and `Manufacturing` then publish it on the website. 4.Buy the product from the website and make the payment. 5.Go to My Account → Your Orders → Open your sale order. 6.In the Manufacturing section, the date appears twice. **Issue-** <img width="604" height="186" alt="image" src="https://github.com/user-attachments/assets/e4164564-8555-4005-8282-20e6f5de7e55" /> - Date found twice in Portal View of sale order **Cause-** https://github.com/odoo/odoo/blob/097c04156517bd97a2789bde22ffd0c69c0bf6bf/addons/sale_mrp/views/sale_portal_templates.xml#L18-L27 - Here using same field two time one it with condition and other is without condition so in some case when condition satisfied then same field are coming twice **Solution-** - Remove Conditional field because no meaning of using same field inside and outside of the condition **opw - 5096009** Forward-Port-Of: odoo/odoo#227997
The cohort reporting view now disables the download option when there is no data to export. This prevents users from running into an error in reports such as Helpdesk Ticket Analysis when the database has no matching records.
Original PR description
Currently, an error occurs when user tries to export data on cohort view with no data. Steps to replicate: - Install `helpdesk` (without demo data). - Go to `Helpdesk > reporting > Ticket Analysis` and go to cohort view. - Click download and error will occur. - If error doesnt occur, click on `Measure > Count`, and click Download again. Error: `IndexError: list index out of range` Cause: - The export button remained enabled even when no data available, this caused the export to be called without any data that caused the `Indexerror` at [1]. Solution: - Disabled the export button when no data in cohort view. [1]: https://github.com/odoo/enterprise/blob/475a802aa3e748a905be83c0f6408f8c20f03905/web_cohort/controllers/main.py#L30 sentry-6831823426 Forward-Port-Of: odoo/enterprise#93050
This fixes a crash that could happen when saving a view or editing a report in Web Studio if the view contained an attribute entry without a name. The system now skips those incomplete entries safely, helping users save views without encountering an unexpected error.
Original PR description
Currently, an error occurs when user tries to save a view with an attribute node without name. **Steps to replicate:** - Initialize a DB and open Views. - Create a new view and fill in random values…
Currently, an error occurs when user tries to save a view with an attribute node without name.
**Steps to replicate:**
- Initialize a DB and open Views.
- Create a new view and fill in random values for name and give a View Type.
- In the Architecture give value as `<attribute></attribute>`.
- Save and you will get the error.
(Same error can also be produced with Web Studio report editor.)
**Error:**
`AttributeError: 'NoneType' object has no attribute 'endswith'`
**Cause:**
- The error occurred because we received **key** as `None` at [1], as it was called from an attribute node with no name [2].
- In `saas-18.2`, we only checked if `node.get('name') not in TRANSLATED_ATTRS`. Since `node.get('name')` was `None` and `None` was not included in the `TRANSLATED_ATTRS` list, no error occurred.
**Solution:**
- Added a conditional check, so that attributes with no name skip the function call.
[1]: https://github.com/odoo/odoo/blob/f254da2253e7ce9426e51112b513fa9e6a474ce4/odoo/tools/translate.py#L83
[2]: https://github.com/odoo/odoo/blob/f254da2253e7ce9426e51112b513fa9e6a474ce4/odoo/tools/translate.py#L190
[3]: https://github.com/odoo/odoo/blob/0b700ec3c08ecd9c6f1597f9d10f6c1eee06bcee/odoo/tools/translate.py#L255
sentry-6877030439
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#227221Spanish TicketBAI POS orders now automatically retry the earlier failed submission when a new order is paid. This helps prevent one failed posting from blocking later sales from being reported, reducing manual follow-up and compliance delays.
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#229180 Forward-Port-Of: odoo/odoo#228477
Swedish Bankgiro and Plusgiro accounts are now handled correctly when generating SEPA payment files and Peppol invoice XML. This prevents missing bank details and helps ensure Swedish payments and e-invoices can be processed successfully.
Original PR description
Bankgiro and Plusgiro accounts in Sweden normally do not have a BIC. However, for Peppol BIS 3 invoices, a BIC tag is required in the XML. The existing _skip_CdtrAgt logic prevents _get_CdtrAgt from being called when no BIC is set, causing the clearing_number to be missing in SEPA payment files for Bankgiro and Plusgiro accounts. This commit introduces overrides for SE-specific account types: _get_cleaned_bic_code: Returns 'SE:Bankgiro' or 'SE:Plusgiro' for Swedish Bankgiro and Plusgiro accounts, ensuring a BIC is present for the invoice XML. _skip_CdtrAgt: Returns False for Bankgiro and Plusgiro accounts to ensure _get_CdtrAgt is called, including the clearing number in the payment file. This guarantees that SEPA payment files and Peppol BIS 3 invoices for Sweden are generated correctly while preserving standard behavior for other banks and countries.
Opening a Knowledge article activity now shows only the relevant articles with assigned activities instead of the full article list. This helps users quickly find the article that needs their attention and avoids confusion in the activities menu.
Original PR description
Currently, when the user tries to open any activity of the knowledge article, it opens all articles instead of the one which has an activity assigned to them. **Steps to reproduce this issue:** 1) Install the Knowledge module 2) Set up an activity for yourself on a Knowledge article 3) Open the activities from Activities (top left corner) **Issue:** You will end up in the all articles list, with no filters applied. **Cause:** When the user clicks on the activities, a default search filter is added in the context, which is then applied on the view. But in the knowledge article, we don't have any search filters for the activities. Therefore, it renders all knowledge article records. **Solution:** Add search filters for the knowledge articles. opw-4997201 Forward-Port-Of: odoo/enterprise#93609
The website shop now handles invalid category values in product page URLs more gracefully. Instead of causing a server error, it returns a clearer validation message, improving stability when links are mistyped or tampered with.
Original PR description
Currently, an error occurs when the `category` is received as a `string` and the code tries to evaluate `int(category)`. **Steps to reproduce:** - Install the `website_sale` module. - Open a product page in the website with an `invalid category` parameter, for example: `http://localhost:8069/shop/warranty-39?category=1;` **Error:** `ValueError: invalid literal for int() with base 10: '1;'` **Root Cause:** At [1], the code directly calls `int(category)` without validating the input. When the parameter contains `non-numeric` characters, Python raises an `error`. **Fix:** This commit ensures raising a `ValidationError`, improving the `error message` clarity, when users manually input `invalid or tampered` category values in the `URL`. [1]: https://github.com/odoo/odoo/blob/d32f98dd199f80d2b0031bd52a6ff74411c3e7e0/addons/website_sale/controllers/main.py#L1827 sentry-6658317828 Forward-Port-Of: odoo/odoo#226207
The POS now correctly recognizes when a self-order has already been sent for preparation, so the Order button is no longer incorrectly highlighted after loading it. This reduces confusion for staff and helps avoid mistakenly thinking an already-submitted order still needs action.
Original PR description
In the POS UI, the "Order" button was wrongly highlighted when loading a self-order, even though it had already been sent Steps to reproduce: - Create an order using self-order mobile (or kiosk). - Open the related POS terminal. - Load the self-order from the ticket screen. - Notice the "Order" button remains highlighted. Fix: - Ensure the last order changes updated when loading self-order in pos Task: 5005161 Forward-Port-Of: odoo/odoo#229246 Forward-Port-Of: odoo/odoo#223560
Nuvei payments could fail when a customer's first or last name was longer than Nuvei allows. The checkout process now shortens those names automatically so affected sales orders can be paid without error.
Original PR description
Steps: - Install sales and payment Nuvei. - Set up payment Nuvei. - Set customer long name and last name. - Try to pay that SO with Nuvei. Issue: - Error. Cause: - Nuvei only accept 30 character for first_name and 40 for last name Fix: - Truncate first and last name to only take required character. opw-5083827 Forward-Port-Of: odoo/odoo#227191
Point of Sale receipts now show the selected shipping date correctly for users in timezones behind UTC, such as US timezones. This prevents customer receipts from displaying the previous day when Ship Later is used.
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
This update fixes an unreliable automated test for the HTML editor by ensuring the editor toolbar is fully ready before the test continues. It helps prevent false test failures, improving confidence in release validation without changing user-facing behavior.
Original PR description
The editor toolbar is affected by [1] and therefore needs to be properly awaited for. This test was missed by [2], probably because it did not explicitly waited for the toolbar itself. runbot-231692 [1]: https://github.com/odoo/odoo/pull/211426/commits/54da715df84789f9a1acc0cfc91be41dcdbab140 [2]: https://github.com/odoo/odoo/pull/213090 Forward-Port-Of: odoo/odoo#227989
The HTML editor now handles tables pasted from tools like ChatGPT when their first row is formatted as a table header. This prevents an error when users delete rows, making pasted table editing more reliable.
Original PR description
**Current behavior before PR:** Steps to reproduce: - Copy a table from chatGPT's response containing first row wrapped in `<thead>`. - Paste it in editor. - Select last row. - Pressing backspace leads to traceback. This issue happens because the copied table is pasted with first row wrapped in a thead element. Due to this, rows are wrongly calculated leading to traceback in removeRow method. **Desired behavior after PR is merged:** - This commit ensures that if a table has first row wrapped inside a `thead`, the row is moved from `thead` to the start of `tbody` ensuring that rows are calculated correctly. task-5048339 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226990 Forward-Port-Of: odoo/odoo#224784
The product image viewer now keeps the selected thumbnail centered when shoppers browse many product images, preventing thumbnails from being cut off at the screen edges. This makes image browsing easier, especially for products with large galleries, and adds smoother swipe navigation on mobile.
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
The project dashboard now prevents users from editing milestone quantity percentages when no sales order line is linked. This avoids confusing failed edits and makes milestone billing data behave consistently with the underlying sales order setup.
Original PR description
**Steps to Reproduce:** - Install sale_project. - Go to the project dashboard. - Click on Edit milestones. **Isuue:** When a sales order line exists, the quantity percentage can be updated. When no sales order line exists, the quantity percentage cannot be updated. **Fix:** Make the field readonly when no sales order line is linked. task-5068312 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227922
The website builder tooltip for the footer visibility option has been corrected so it no longer describes the opposite behavior. This helps users understand whether the footer will be shown or hidden when adjusting page visibility settings.
Original PR description
A tooltip message was added to the option for the visibility of the footer in e0474c19d212d9c19fd1c3bbc9546b4258770018. The message indicates the opposite of the effect. This commit changes the message to match the behavior of the checkbox. Steps to reproduce: - Open website builder - Click on footer - Hover "Page Visibility" - Bug: the message "Enable to hide...", but enabling actually shows task-4991435
This fixes an issue in the HTML editor where images added from an empty formatted line could disappear after the user clicked elsewhere. The change preserves the inserted image during editor cleanup, helping users avoid lost content while composing pages or messages.
Original PR description
Problem: When an image is added inside a `data-oe-zws-empty-inline`, it is removed along with its parent during normalization. Solution: During normalization, replace `data-oe-zws-empty-inline` with the image inside instead of removing both. Steps to reproduce: - Press CTRL+B in an empty line - Press Enter - Click on "Insert image, ..." from the placeholder - Choose an image - Click in the previous paragraph - The image disappears without this fix task-5051343 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228620 Forward-Port-Of: odoo/odoo#224922
The website and HTML editing tools now use Odoo’s slimmer close icon for a cleaner, more consistent interface. Some button layouts and dropdown behavior were also corrected so controls align better and remain usable on smaller screens.
Original PR description
This commit replaces occurrences of `fa-times` in the html builder and editor with our own `oi-close` icon, which is less bulky and more elegant. It also corrects button structures where icon classes were placed directly on the `button`, ensuring they are applied to a child `<i>` element as intended. It also ensures `.o-hb-selectMany2X-wrapper` has `min-w-0` so the dropdown is truncated properly without pushing the remove button out of the screen. task-5090805 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix restores the initialization needed for Turkish localization reports to load correctly. It resolves failures such as the Turkish General Ledger report not opening, helping affected users access required accounting reports again.
Original PR description
## Before this commit: The referenced commit removed `from . import models` from the module’s `__init__.py`. As a result, the files inside `l10n_tr_reports/models/` (such as `account_general_ledger.py`) were not loaded. This prevented their logic from being executed and caused issue like the Turkish General Ledger report to fail to load. Ref commit: https://github.com/odoo/enterprise/commit/a86bc92f9358eed458872a3e60d5c3c791b3860c ## After this commit: Reintroduced the missing import in `__init__.py`, ensuring that the models package is initialized correctly and all related reports and functionality work as intended.
11 changes
New functionality added to Odoo
Adds automated and manual synchronization with Romania's ANAF e-Factura service so businesses can update invoice statuses and receive validated vendor bills directly in Odoo. This reduces manual follow-up, helps avoid duplicate bills, and lets companies choose the accounting journal used for automatically created ANAF bills.
Original PR description
Backport of the odoo/odoo#208082, adding the possibility to synchronize invoice and bill status at once. The endpoint `ListaMesajeFactura` returns a list of messages to process. Those messages can: -…
Backport of the odoo/odoo#208082, adding the possibility to synchronize invoice and bill status at once. The endpoint `ListaMesajeFactura` returns a list of messages to process. Those messages can: - Return an invoice status update with a success or an error; - Return a new bill from another vendor already validated by the authority. The messages contain a message ID to recover and download the official data from the ANAF server: the invoice/bill XML and the signature. (documentation)[https://mfinante.gov.ro/static/10/eFactura/prezentare%20api%20efactura.pdf] When synchronizing, we retrieve the new messages from the last 24 hours and update the database content accordingly: - in case of invoice status update, update the relevant invoice/bill status and download the signature in case of success (note that this was already done before, we only call the relevant methods to do so); - in case of a new vendor bill, we download the bill XML and signature, create a new in_invoice move and fill it up with the XML content. In case a bill with the same index is already in the database, we do nothing to avoid duplicate. If a similar bill (same date and amount) is found but not yet validated, we only validate it. The synchronization can be triggered manually through the option in the list view and it is automatically triggered every 4 hours with a CRON. Lastly, the created bill journal can be set up in the Accounting settings so that users can specify their favorite journals for automated ANAF bills. task-4891081 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221324
Resolved issues and error corrections
Accrued expense entries for purchase orders now show the amount after discounts instead of the full pre-discount amount. This helps finance teams see more accurate purchase-related accruals and avoid overstating expenses.
Original PR description
Steps to reproduce: [purchase] - Create a purchase order - add a line with a discount - confirm and receive - create an accrued expense entry Issue: The full tax excl amount is displayed but no discount is applied opw-5049848 Forward-Port-Of: odoo/odoo#225375
This fix narrows a checkout test so it focuses on confirming public access for click and collect orders. It reduces inconsistent automated test behavior where very fast test steps could accidentally create two orders instead of reusing the first one, helping keep future updates safer and more dependable.
Original PR description
Tours are too fast for imitating the user actions that led to sometimes creating 2 orders in parallel instead of reusing the first created. The test was added for b395f984b13eb83310024b9fa94d7822211ef8c1 fix, so with this commit, we keep the test more specific to the fix and avoid inconsistent behavior.
This fixes the stock quantities list so regular stock users no longer see every product highlighted in red. Red highlighting now appears only for products that have an expired removal date, making the list easier to read and helping users focus on items that need attention.
Original PR description
Description of the issue/feature this PR addresses: For stock users (not admins), the stock quantities list view display red lines for every product. Current behavior before PR: <img width="2243" height="217" alt="image" src="https://github.com/user-attachments/assets/330c591c-6ef4-46cb-8336-fa39fb483333" /> Desired behavior after PR is merged: Red lines are only displayed for products with a removal date and a removal date < current date <img width="2241" height="290" alt="image" src="https://github.com/user-attachments/assets/fe37adc7-e736-447e-a21e-e2fae984e074" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Live chat visitors can no longer start calls or invite additional guests from a chat thread. This prevents unintended use of communication features and keeps live chat interactions within the intended support flow.
Original PR description
This commit removes the possibility for live chat visitors to start a call and invite guests. task-4849019
This fix ensures Italian point-of-sale receipts are printed for the order that was just completed, even when automatic printing skips the receipt screen. It prevents staff or customers from receiving a receipt for a newly created empty order instead of the actual sale.
Original PR description
Before this commit, the printReceipt logic in the module l10n_it_pos would not pass the order to be printed. This can become a problem upon context changes, where pos.get_order does not return the completed order, but a newly created one. This can for example happen when skipping the receipt screen with the option to "print automatically" (iface_print_auto). After this commit, we keep order as an argument, so we always print the last completed order and not a newly created one. opw-4882480
Fixes Italian fiscal printer receipts not printing when the point of sale is configured to skip the receipt screen. The change ensures the correct completed order is sent to the fiscal printer, preventing missed receipts and printer errors during checkout.
Original PR description
This PR fixes two related bugs happening when printing a receipt with the Italian Fiscal printer First, before this PR, if the option to skip the receipt screen was ticked, then the receipt would…
This PR fixes two related bugs happening when printing a receipt with the Italian Fiscal printer First, before this PR, if the option to skip the receipt screen was ticked, then the receipt would never print. This was caused by the printing logic being implemented on the receipt screen instead of on the pos itself. steps to reproduce: 1. install l10n_it_pos 2. configure one pos 3. configure the IT printer 4. select to skip the receipt screen (print automatically) 5. open the pos 6. make a sale => no ticket printed and the chrome console shows a printer error With this new verison the printing logic was moved to the pos so that printing of fiscal receipts with the italian fiscal printer works, even when receipt screen is skipped. This put to light another potential bug related to how the `order` variable was treated. Before this PR, the printReceipt logic in the module would not pass the order to be printed. This can become a problem upon context changes, where `pos.get_order()` does not return the completed order, but a newly created one. This can for example happen when skipping the receipt screen with the option to "print automatically" (iface_print_auto). After this PR, we keep order as an argument, so we always print the last completed order and not a newly created one. opw-4882480
Swedish domestic payment files will now include the creditor bank agent information when required. This helps ensure payment files meet Swedish banking expectations and reduces the risk of payment processing issues.
Original PR description
CdtrAgt should not be skipped when generating swedish domestic payments.
Customers viewing an online order that includes a manufactured product will no longer see the same manufacturing date twice. This keeps the order portal cleaner and avoids confusion when checking order and production details.
Original PR description
**Steps to reproduce:** 1.Install `website_sale` and `sale_mrp`. 2.In settings, enable `multi-route` and `unarchive` the Replenish MTO route. 3.Create a product with routes -> `Replenish MTO` and…
**Steps to reproduce:** 1.Install `website_sale` and `sale_mrp`. 2.In settings, enable `multi-route` and `unarchive` the Replenish MTO route. 3.Create a product with routes -> `Replenish MTO` and `Manufacturing` then publish it on the website. 4.Buy the product from the website and make the payment. 5.Go to My Account → Your Orders → Open your sale order. 6.In the Manufacturing section, the date appears twice. **Issue-** <img width="604" height="186" alt="image" src="https://github.com/user-attachments/assets/e4164564-8555-4005-8282-20e6f5de7e55" /> - Date found twice in Portal View of sale order **Cause-** https://github.com/odoo/odoo/blob/097c04156517bd97a2789bde22ffd0c69c0bf6bf/addons/sale_mrp/views/sale_portal_templates.xml#L18-L27 - Here using same field two time one it with condition and other is without condition so in some case when condition satisfied then same field are coming twice **Solution-** - Remove Conditional field because no meaning of using same field inside and outside of the condition **opw - 5096009** Forward-Port-Of: odoo/odoo#227997
This fix ensures the mailing list merge wizard correctly identifies the destination list when starting a merge. It prevents an error during merge setup, making list consolidation more reliable for marketing teams.
Original PR description
When merging mailing lists, the logic for pre-filling the destination list
ID ('dest_list_id') was incorrectly retrieving and checking 'src_list_ids'
(source lists) instead of the list of potentially active/destination IDs.
This change modifies the assignment to use 'dest_list_id' (or the active
context IDs) for determining the default value, resolving an error when
initiating the merge wizard.
Closes #228958
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-prFixes an issue in the HTML editor where the color picker closed unexpectedly when previewing background colors for a table cell. This keeps the editing flow stable so users can choose table cell colors without interruption.
Original PR description
Problem: When applying a background color to a `td`, the color picker dismisses unexpectedly. Cause: After c810b0c17b2f882b0ab5d073ba38464bffb0617e, we rely on the class `o_selected_td` to check if…
Problem: When applying a background color to a `td`, the color picker dismisses unexpectedly. Cause: After c810b0c17b2f882b0ab5d073ba38464bffb0617e, we rely on the class `o_selected_td` to check if we are in a selected `td` to keep the toolbar open. However, in another fix (254efd86cd1ce871807fdc25479ebc5beeb4eab3), we removed that class during the color preview operation. Previewing a color on a `td` triggers a selection change, which runs `shouldBeVisible`. Since `o_selected_td` is not found, the toolbar closes along with the color picker. Solution: Update https://github.com/odoo-dev/odoo/commit/254efd86cd1ce871807fdc25479ebc5beeb4eab3. A better fix is to use `o_selected_td_bg_color_preview` which will undo the `box-shadow` when we preview a color. Steps to reproduce: 1. Add a table. 2. Select a cell. 3. Apply a background color. 4. Select the cell again. 5. Hover a color to preview. → The color picker dismisses once a color is hovered. opw-5066309 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
6 changes
Resolved issues and error corrections
This fix updates Vietnamese tax data during migration without reloading the full accounting setup. It helps preserve company-specific tax and configuration customizations while still applying the required tax updates.
Original PR description
Problem The previous implementation used try_loading() which would reload the entire chart template, potentially overwriting user-customized configurations settings. Solution Replaced try_loading() with a more targeted approach usin _load_data for account.tax.group and account.tax 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
Signed signature requests can no longer be deleted once they have been completed. This helps preserve signed records and avoids accidental loss of important agreement history.
Original PR description
backport of https://github.com/odoo/enterprise/commit/b2d32811877cdf1649095435ce16274ae96421f3 opw-5111568
The favorite star in Documents spreadsheets now immediately shows the correct selected or unselected state on mobile devices. This avoids confusion when users mark or unmark a spreadsheet as a favorite and keeps the behavior consistent with the rest of Odoo.
Original PR description
The star icon on mobile would have a strange behaviour. After clicking it, the star would not change between filled/not filled until clicking elsewhere. It turns out that on mobile, after a click the hover rule is applied. And our hover rule would modify the icon to be the opposite of what it should be. This commit changes the CSS to use the same css as `BooleanFavoriteField` to stay consistent with the rest of Odoo. Task: [5092945](https://www.odoo.com/odoo/2328/tasks/5092945)
Recurring invoicing now skips subscriptions linked to archived companies. This prevents unwanted invoices from being generated while a company is inactive, keeping billing aligned with business status.
Original PR description
## Issue: When a company with active subscriptions is archived, the recurring invoicing cron still processes these subscriptions. Subscriptions for archived companies must not be invoiced. ## Steps to reproduce: 1. Create a company A. 2. Create a subscription for company A with next invoice date <= today. 3. Archive the company. 4. Run the scheduled action "Sale Subscription: generate recurring invoices and payments". 5. Unarchive the company and check the subscription. It should not have been invoiced. (Adjust the user's Allowed Companies if needed to access it.) backport-of: a93e7ec opw-4904325
Duplicated CRM leads without an assigned salesperson now stay eligible for rule-based assignment. This prevents sales opportunities from being skipped by automated assignment workflows after duplication.
Original PR description
Currently, leads are not automatically assigned via rule-based assignment when duplicating an existing lead, even if the duplicated lead matches the assignment criteria. **Pre-requisites:** 1) Set up…
Currently, leads are not automatically assigned via rule-based assignment
when duplicating an existing lead, even if the duplicated lead matches
the assignment criteria.
**Pre-requisites:**
1) Set up rule-based lead assignment in the CRM settings.
2) Configure the sales team's assignment domain:
`[("user_id", "=", False)]`
3) Configure the sales team members' domain:
`[("probability", ">=", 10)]`
**Steps to Reproduce:**
1) Create a lead that matches the above assignment rules.
2) Remove the salesperson (user_id) and sales team from the lead.
3) Duplicate the lead.
4) Update the probability to a valid value (e.g., ≥ 10).
5) Manually trigger the `Rule-Based Assignment`.
**Issue:**
The original lead gets assigned, but the duplicated one does not.
**Cause:**
When duplicating, the system sets date_open to the current date by default,
even if the duplicated and original leads have no assigned users.
https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_lead.py#L929-L931
However, `rule-based assignment` only considers leads where `date_open` is False https://github.com/odoo/odoo/blob/3e7d85cf25386615dea559d954cebb1424b62f35/addons/crm/models/crm_team_member.py#L136-L141
**Solution:**
Set `date_open` to False during duplication if the original lead has no `user_id`.
This ensures the new lead remains eligible for assignment.
opw-5003529Removes a redundant database rule in the Mail app that could conflict with newer PostgreSQL versions. This helps newly created databases remain compatible with PostgreSQL 18 and reduces the risk of restore or upgrade failures.
Original PR description
The field is `required=True`, which automatically sets it `NOT NULL` (if possible). The constraint does not do anything useful. Furthermore, pg18 promoted `NOT NULL` to "real" named constraints[1],…
The field is `required=True`, which automatically sets it `NOT NULL` (if possible). The constraint does not do anything useful.
Furthermore, pg18 promoted `NOT NULL` to "real" named constraints[1], and the constraint was created following the pattern pg uses, so trying to migrate a database to pg18 (either upgrading a cluster from 17 to 18 or restoring a db on a pg18) the restoration fails with
duplicate key value violates unique constraint "pg_constraint_conrelid_contypid_conname_index"
The easiest fix is to delete the constraint in the upstream DB if possible (I didn't find a way to filter out constraints from pg_dump or pg_restore, though it should be possible to filter it out from a "plain" dump by hand).
AFAIK Odoo does not generally drop constraints so I don't think this will fix existing databases, but it at least makes future databases compatible with pg18.
[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=a379061a22a8fdf421e1a457cc6af8503def6252
Forward-Port-Of: odoo/odoo#229274