Thursday, September 11, 2025
18 changes · saas-18.4
Resolved issues and error corrections
This fix prevents protected links in the HTML editor, such as locked website builder links, from being removed through image deletion, toolbar unlink actions, or mixed editable/non-editable content. It helps preserve important page structure and avoids broken toolbar rendering after editing.
Original PR description
### [FIX] html_editor: prevent removal of unremovable links with images The override that remove a link on `deleteImage` command did not check if the link was unremovable before removing it. ###…
### [FIX] html_editor: prevent removal of unremovable links with images The override that remove a link on `deleteImage` command did not check if the link was unremovable before removing it. ### [FIX] html_editor: prevent removal of links in contenteditable=false If a link was `contenteditable=true`, but inside a `contenteditable=false`, it could be removed ### [FIX] html_editor: prevent removal of unremovable links in batch removal If the selection covers several links, the "unlink" of the toolbar removes all the links selected. This included the links which were supposed to be unremovable. The procedure for removing the links is changed to avoid removing the unremovable nodes. The availability of the tool in the toolbar is also changed to better reflect whether there is links to remove. In case of unremovable links, the tool is shown as disabled Steps to reproduce: - Open website builder - In the toolbar, insert links just before and after the "Contact Us" - Select from the link inserted before, to the one after - In the toolbar, click "Remove Link" - Bug: the link on "Contact Us" is gone, but it was "unremovable" (Saving after these steps currently breaks the toolbar's rendering)
The online shop wishlist now works even when the website header is disabled, preventing shoppers from encountering a crash. Wishlist indicators are also updated consistently across desktop and mobile views, improving the shopping experience.
Original PR description
__Current behavior before commit:__ It is possible to hide the header on the website. If it is hidden, the `_updateWishlistView` method will not find `.my_wish_quantity` in the page; leading to a crash. Furthermore, the current implementation only updates the first wishlist button. However there is a second one in the DOM for the mobile view. __Description of the fix:__ Looping through all the wishlist buttons on the page just like it is done in [master]. __Steps to reproduce the issue on runbot:__ 1. Open the mobile preview on the website 2. Go to `/shop` and add an item to the wishlist => The wishlist button is not updated 1. Open the website builder 2. In the Theme tab, disable *Advanced > Show Header* 3. Go to `/shop` => Crash [master]: https://github.com/odoo/odoo/blob/d65163ea740d8d65/addons/website_sale_wishlist/static/src/js/website_sale_wishlist_utils.js#L57-L60 Bug introduced in: https://github.com/odoo/odoo/pull/212584 opw-4959473
Users with invoicing permissions can now update perception and withholding settings on partner records in the Argentine withholding module. This helps invoice creators apply the correct tax treatment without needing full Accounting administrator access.
Original PR description
Description of the issue/feature this PR addresses: This pull request adds `l10n_ar.partner.tax_billing` on the `l10n_ar_partner_tax` model, granting read, write, and create permissions (but not…
Description of the issue/feature this PR addresses: This pull request adds `l10n_ar.partner.tax_billing` on the `l10n_ar_partner_tax` model, granting read, write, and create permissions (but not unlink) to users in the `account.group_account_invoice` group. Current behavior before PR: Only users with administrator access rights on the Accounting module could modify the "Perceptions / Withholdings" Section on the "Accounting" tab of the partners. <img width="1236" height="673" alt="image" src="https://github.com/user-attachments/assets/92b42973-2b01-4019-8e23-5e3cbf5111a4" /> Desired behavior after PR is merged: Users with invoicing rights can modify the Accounting module could modify the "Perceptions / Withholdings" Section on the "Accounting" tab of the partners. This is needed to properly create the invoices with the perceptions / withholding that apply, for example in cases where by default all partners are set with perceptions, but some depending on their activity are not taxed. In that case, the user that created the partner needs to be able to modify the field by putting a 0% aliquot or deleting the perception line on the contact. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225180
Odoo now blocks pricelist rules that depend on each other in a circular way. This prevents online shop errors when customers select affected pricelists and helps keep pricing setup reliable.
Original PR description
Steps ----- 1. Create a selectable pricelist A; 2. create a selectable pricelist B; 3. add a rule to pricelist B which uses pricelist A; 4. add a rule to pricelist A which uses pricelist B; 5. go to /shop & select one of the pricelists. Issue ----- > 500: Internal Server Error > Error while render the template > RecursionError: maximum recursion depth exceeded in comparison Cause ----- The `_check_pricelist_recursion` constraint only checks if a pricelist item's `base_pricelist_id` is the same as the item's `pricelist_id`. It can therefore not detect if two or more pricelists have a mutually recursive dependence relationship. Solution -------- Use a depth-first search to ensure any dependent pricelist doesn't depend on a parent pricelist. opw-5070604
Customers can now add Stripe payment methods without encountering an internal server error during validation. The fix handles Stripe validation responses that do not include amount or currency details, improving reliability of saved payment method setup.
Original PR description
Versions -------- - saas-18.4+ Steps ----- 1. Configure Stripe; 2. go to `/my/payment_method`; 3. create a payment token. Issue ----- > Internal Server Error Cause ----- Commit 5db75d32d718a added a…
Versions
--------
- saas-18.4+
Steps
-----
1. Configure Stripe;
2. go to `/my/payment_method`;
3. create a payment token.
Issue
-----
> Internal Server Error
Cause
-----
Commit 5db75d32d718a added a method that compares notification data values to the transaction values. For most operations, the structure of Stripe notification data is similar, but for `SetupIntent` responses, these don't include an amount or currency value (unless the currency is supported by Indian eMandates, in which case it's part of a `mandate_options` dict)[^1].
The error is the result of `payment_data.get('currency').upper()`. Because there is no currency value, `upper` gets called on `None`.
Additionally, when the transaction amount is zero (as is expected for validation operations), the base `_compare_notification_data` method assumes the amount is missing, throwing a validation error.
[^1]: https://docs.stripe.com/api/setup_intents/confirm
Solution
--------
- Skip comparing notification data for validation transactions.
- If the `currency` value is in fact missing unexpectedly, fall back on the empty string, so that we get to the intended validation error.
opw-5008858This update refreshes the spreadsheet component and fixes several issues affecting everyday spreadsheet use. Users should see cleaner Excel imports, fewer unnecessary warnings, better handling of array formulas, and improved menu text display.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/15a11a468 [REL] 18.4.10 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/15a11a468 [REL] 18.4.10 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/8e9603c88 [FIX] package: saas-18.4 is no longer the latest version [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/d021c7ff6 [FIX] Menu: Fix item text truncation [Task: 5072649](https://www.odoo.com/odoo/2328/tasks/5072649) https://github.com/odoo/o-spreadsheet/commit/424fb57e8 [FIX] xlsx: remove useless warnings on import [Task: 5075112](https://www.odoo.com/odoo/2328/tasks/5075112) https://github.com/odoo/o-spreadsheet/commit/c3bad9029 [FIX] clipboard: insert cells bugged with array formulas [Task: 4938311](https://www.odoo.com/odoo/2328/tasks/4938311) https://github.com/odoo/o-spreadsheet/commit/f4282501a [FIX] xlsx: `=undefined` when importing array formula [Task: 4812508](https://www.odoo.com/odoo/2328/tasks/4812508) https://github.com/odoo/o-spreadsheet/commit/eb13639d0 [REV] xlsx: make import verbose [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Event registration screens now show the correct action button depending on seat availability and whether tickets are free. This prevents visitors from seeing a misleading sign-in option that could lead to an error or confusion during registration.
Original PR description
This commit fixes two bugs related to the "Sign in" in button of the registration form. First bug: ------------ If there is more ordered seats than available seats, an error modal is displayed with a…
This commit fixes two bugs related to the "Sign in" in button of the registration form. First bug: ------------ If there is more ordered seats than available seats, an error modal is displayed with a "Sign In" button. This button shouldn't be present. On click, a 500 error is triggered. Now, the button does not appeared on this modal. Reproduce: Check "Mandatory" for "Sign in/up at checkout" in the settings. In the event form, add a limit of 1 available seat and add two tickets with each one 1 seat. With a public user, on the website page of the event, click on "Register" to open the registration modal. In the tickets form, select the maximum number of registrations for each tickets. The error modal with the "Sign In" button should appear. Clicking on this button trigger the 500 error. Second bug: ---------------- The "Sign in" button is displayed even if the tickets have no price. So the label of the button is wrong because public users are not redirected to the checkout. Now, the "Confirm Registration" button is displayed in this case. Reproduce: With the same settings as for the first bug, create an event without tickets. Order a registration with an public user. Click on the "Sign In" button of the attendee details form. The confirmation page appears instead of the sign in page. task-4797022 Forward-Port-Of: odoo/odoo#215585
This fixes a crash that occurred when adding a kit product as a part on a repair order. Users can now save repair orders with kit components normally, reducing interruptions in repair workflows.
Original PR description
When user tries to set the kit as product parts in repair order, A traceback will appear. Steps to reproduce the error: - Install ``mrp_repair`` module with demo data - Create a new repair order > In Parts, Add a line > Product: ``Table Kit`` > Save Traceback: ``AttributeError: 'stock.move' object has no attribute 'name'`` https://github.com/odoo/odoo/blob/83a8508b958ed88bbdbf80612039ec33817bc02c/addons/mrp_repair/models/repair.py#L84 The ``name`` field of ``stock.move`` was removed in the [commit](https://github.com/odoo/odoo/pull/211488/commits/f3fc7a5cfd6e77cbbcfff891383abeac930d41ac), but it is still being referenced here. So, It will lead to the above traceback. sentry-6870866512 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Live chat routing now correctly ignores conversations that have already ended or have been inactive for at least 30 minutes when measuring agent workload. This helps assign new chats to the truly least busy available agent, improving response distribution and customer handling.
Original PR description
Live chat agents are assigned based on their expertise, language, country, and other criteria. When several agents match these criteria, the system chooses the least active one. There was an issue with the SQL query that retrieves agent occupation: an agent was still considered buisy if a message was received within the last 30 minutes, even if the live chat was ended. This commit fixes the issue: the query now excludes ended live chats as well as live chats without any activity for at least 30 minutes. task-5065567 Forward-Port-Of: odoo/odoo#226271 Forward-Port-Of: odoo/odoo#225514
Fixes an issue in the website builder translation mode where using left or right arrow keys inside carousel text could switch slides and then cause a crash. This keeps text editing predictable for multilingual website content and prevents disruption while translating carousel snippets.
Original PR description
Since the initial [website builder refactor], when in translate mode in website builder, pressing an arrow key when the cursor is inside the text of a carousel moved to the next slide once, pressing…
Since the initial [website builder refactor], when in translate mode in website builder, pressing an arrow key when the cursor is inside the text of a carousel moved to the next slide once, pressing again caused a crash. Before the refactor, there was also the slide behavior but not the crash. The arrows triggers the slide because the contenteditable is inside the slide in translate mode. It does not trigger it in normal edit mode because the contenteditable is on an ancestor. This commit fixes it by changing the config pass to the bootstrap carousel in edit mode, so that the carousel does not slide on keyboard. Changing this config makes the event handlers to stop the keydown event on the other parts of the carousel redundant, so they are removed Steps to reproduce: - Open website bulider - Drop the snippet "Quotes Minimal" - Add a second language to the website - Edit the translation for the second language - Click on the text in the quote in the carousel - Press a left or right arrow key - Bug: the slide changed (instead of moving the cursor in side the text) - Click on the text of the slide that is now shown - Press again the arrow key - Bug: Crash [website builder refactor]: https://github.com/odoo-dev/odoo/commit/9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-4367641
This fixes an error that could prevent portal users from buying a paid eLearning course after accessing it through a shared preview link and completing a quiz. The cart action now uses the current shopping cart mechanism, so learners can continue to checkout normally.
Original PR description
Steps to reproduce: 1) Install `website_sale_slides`. 2) Create a course with enroll policy 'On payment' and publish it. 3) Add a content allow preview it and add a quiz 4) Go to website, click Share…
Steps to reproduce:
1) Install `website_sale_slides`.
2) Create a course with enroll policy 'On payment' and publish it.
3) Add a content allow preview it and add a quiz
4) Go to website, click Share button and open the generated link in incognito.
5) Login as a portal user, pass the quiz and click "Buy this course".
Issue:
- A traceback occurred:
`Cannot read properties of undefined (reading 'addToCart')`.
Cause:
- The method call `self.call('websiteSale', 'addToCart', ...)` relied on the deprecated `call` service, which was removed in commit https://github.com/odoo/odoo/commit/b8d0ab4275b24510161de9db793020f3489b0446.
- The service and method `call('websiteSale', 'addToCart'` is not valid and was not updated here :
https://github.com/odoo/odoo/blob/35161ecf0dd3fde47db9b2166718339c2e30ac92/addons/website_sale_slides/static/src/js/slides_course_join.js#L29
- As a result, `addToCart` was no longer accessible and triggered a JS error.
Solution:
- Update the code to use the new service and method: `call('cart', 'add',`
opw-5045424
Forward-Port-Of: odoo/odoo#224760Creating an invoice no longer crashes when VAT verification is enabled and the company has no country set. The change adds a safeguard so customers can continue invoicing even if company country data is incomplete.
Original PR description
The system crashes with an error when a user tries to create an invoice. **Steps to produce:-** - Install `Accounting` module and switch to `BE Company`. - Go to `Settings > Users & Companies >…
The system crashes with an error when a user tries to create an invoice.
**Steps to produce:-**
- Install `Accounting` module and switch to `BE Company`.
- Go to `Settings > Users & Companies > Companies` and remove the country from the BE company.
- Create a new customer with:-
- Country as `Belgium`.
- Tax ID as `DE123456788`.
- `Accounting > configuration > settings > enable Verify VAT Numbers`.
- Now try to make `invoice` with customer as previously created customer.
**Error:-**
`TypeError : argument of type 'bool' is not iterable`
**Root cause:-**
- At [1], the code attempts to access `company.country_id`, but since the country was manually removed from the company, it evaluates to null record, leading to the error.
**Solution:-**
- Add a safeguard to ensure `company.country_id` also exist before accessing `country_group_codes`.
[1] -https://github.com/odoo/odoo/blob/4c2330f3cc0d1a0046e28d351f894763aeea57d2/addons/base_vat/models/res_partner.py#L764
**sentry-6851141424**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#225158Point of Sale now avoids an error when taxes are turned back on after a product has already been added to an active sales session. This keeps cashiers from seeing a crash and helps ensure updated tax settings are handled smoothly.
Original PR description
Steps to reproduce: ---- - From accounting disable taxes - Create new product - Open PoS UI and add product in orderline - Go to backend and enable taxes - Add tax in previously created product - Open UI again Issue: ---- - We will have traceback Cause: ---- - undefined error as pos_receipt_label is undefined as we don't have chance to reload data as product is already in orderline Fix: ---- - added optional chaining so we don't have undefined error also we have to reload data after enabling taxes from the configurations in the backend ---- task - 4762770 Forward-Port-Of: odoo/odoo#208511
The Swiss financial reports now show previous-year unallocated profit and loss correctly. The balance sheet also separates current-year earnings into retained and allocated amounts, giving businesses a clearer view of profit allocation.
Original PR description
Before this commit, `Previous Year unallocated profit and loss` was showing wrong amount. With this commit, we adapt this line (change period of one of its expression) and we add two new lines to reflect the actual year earnings, retained and allocated. Steps, with fresh db: - 1 invoice confirmed in the past year for 1000 - Create the carryforward move (1000 debit for 999 account, and 1000 credit for 2979 account) - Go to balance sheet, set date as 'End of last fiscal year' -> See 'Previous Years Unallocated Earnings` showing -1000 opw-4054341 Forward-Port-Of: odoo/enterprise#94243 Forward-Port-Of: odoo/enterprise#91281
Appointment bookings now calculate manual confirmation thresholds using the combined capacity of all assigned users, rather than a single user's capacity. This prevents valid bookings from being unnecessarily marked as requests when enough total capacity is still available.
Original PR description
ISSUE ===== Introduced in bce7e94650c337a9046958a7689c81db5b2a4c73, We now handle capacity when booking users. They have each a max capacity of user_capacity for each slot. However, when it comes to…
ISSUE ===== Introduced in bce7e94650c337a9046958a7689c81db5b2a4c73, We now handle capacity when booking users. They have each a max capacity of user_capacity for each slot. However, when it comes to the manual confirmation treshold, we do not account for the total capacity of all users combined, but consider the maximum to be user_capacity! This can lead to a lot of 'request' meetings as we reach the manual confirmation percentage very quickly. STEPS TO REPRODUCE ================== 1. Create an appointment type based on users, with 'manage capacities' enabled, 'manual confirmation' enabled and 'when over' 50% total capacity. Set 2 users and 3 'seats max'. This way, the total capacity of your appointment is 2 * 3 = 6 per slot. 2. As a public user, take an appointment for 2 capacity in the front end 3. The meeting will end up as a 'request', even though the capacity booked is 2/6 < 50%, and should be 'booked' FIX === We now multiply the number of users on the appointment type by the user_capacity when computing the total capacity and comparing it to the asked capacity on booking an appointment. A test is included Task-4930778
This fix prevents an error when users add improvement suggestions to extra manufacturing work orders that were not part of the original bill of materials. It avoids creating unsupported quality control records in that situation, so duplicated manufacturing orders can continue through shop floor steps without crashing.
Original PR description
## Issue: Creating multiple suggestions sequences for differents Workorder in Manufacturing Orders that are added aside BoM defined WorkOrder cause an issue with a Traceback error ## Cause: In the…
## Issue: Creating multiple suggestions sequences for differents Workorder in Manufacturing Orders that are added aside BoM defined WorkOrder cause an issue with a Traceback error ## Cause: In the method `add_check_in_chain()`, the `point.sequence` cause issue because the check can have multiple points https://github.com/odoo/enterprise/blob/e85d11f9b3bf07a55e5365adac7370955a149566/mrp_workorder_plm/models/mrp_workorder.py#L58-L66 That the case because multiple quality checks sequences are created when the operation_id is False That's unexpected because PLM isn't made to suggest WorkOrder additions and Suggestions to New WO, but only Suggestions to existing operations So we avoid to create `quality.point` when there is no operation_id ## Information: To get the Traceback, you need to install Quality_control because this module will copy the QC to the MO including the one with operation_id set to False ## Steps to reproduce: Quality_control and plm need to be installed - Enable Work Orders in Settings - Create a Product with a BoM - Create a MO for the Product - Add an extra WO - In the Shop Floor, Mark as Done the BoM's WO - On the Extra WO, click Gear Icon > Update Instructions > Improvement Suggestion > Add a Step - Insert a Title and Propose Change - Duplicate the MO and redo the Shop Floor steps to get the Traceback opw-4874108 Forward-Port-Of: odoo/enterprise#92384
Paid appointment bookings could incorrectly fail by saying a slot was no longer available when resources had capacity greater than one. The fix ensures these bookings count only one simultaneous appointment when capacity management is disabled, allowing customers to complete payment for valid slots.
Original PR description
ISSUE ===== Introduced in odoo/enterprise@bce7e94650c337a9046958a7689c81db5b2a4c73 , we now allow configuring a number of max simulatenous appointments per resource / user per slot, when…
ISSUE ===== Introduced in odoo/enterprise@bce7e94650c337a9046958a7689c81db5b2a4c73 , we now allow configuring a number of max simulatenous appointments per resource / user per slot, when manage_capacity is False. However, this broke the booking flow when enabling a payment on the appointment type as well, for resources with capacity > 1. More specifically, as soon as the remaining capacity is lower than the resource's own capacity. STEPS TO REPRODUCE ================== 0. Install payment_demo, in order to be able to test the payment issue. Install website_appointment_sale to ease the testing too. 1. Create an appointment type for 'Resources', enable 'Up-front payment'. 2. Set a new resource with capacity = 2 on the appointment type. 3. Make sure manage_capacity is False, and number of simultaneous appointments (max_bookings) is set to 1. 4. Go to the front end and pick any slot. 5. Fill the form and 'proceed to payment' 6. Try to 'pay now' 7. You get a validation error message telling you that the slot is not available anymore. But it is not the case since it is a new type and new resource. FIX === For resources, created booking lines were setting capacity_used to the resource's capacity, unless shared. (meaning: the resource is completely used, even if the reserved quantity is smaller). It made sense before but not for this new feature. It should only use 1 capacity, as we count the number of different simulatenous appointments, and it is unrelated to the resource's own capacity. When creating the meeting at the end of the regular flow, the computed field on capacity_used on appointment.booking.line will set it to 1 when manage_capacity is False. Hence, no issue will happen there in practice as the meeting is always created in that case and capacity_used updated. However, when enabling a payment, we create a calendar.booking instead, with calendar.booking.lines. And based on those, we evaluate availability when checking the cart before going to payment. Those are simply created from values in the controller, and the model is much simpler. Therefore, we fix the issue by manually setting the capacity_used to 1 when creating the booking lines in the front-end booking flow, in the case of an appointment without capacity management. Task-4963012
The Chilean electronic factoring process now handles failed or invalid responses from the tax authority more safely instead of crashing. It also refreshes invalid access tokens and adds test coverage, improving reliability when the external service has intermittent issues.
Original PR description
There were some typos in this method. We add test coverage and we reset the token in situations where we receive invalid responses. It's apparently common for the SII to have some random errors that could result in invalid tokens being generated. Based on the work in https://github.com/odoo/enterprise/pull/92035. Forward-Port-Of: odoo/enterprise#94342 Forward-Port-Of: odoo/enterprise#94134