Thursday, July 30, 2026
34 changes · saas-19.3
Enhancements to existing features
This PR adapts the update dialog to fit the new update logic which is individual to every iot box related PR: https://github.com/odoo/odoo/pull/278661 Forward-Port-Of: odoo/odoo#278914
Original PR description
This PR adapts the update dialog to fit the new update logic which is individual to every iot box related PR: https://github.com/odoo/odoo/pull/278661 Forward-Port-Of: odoo/odoo#278914
Resolved issues and error corrections
The French accounting reports test suite was updated to match a recent change in how FEC export labels are chosen when fallback information is needed. This helps keep compliance-related exports reliable and prevents false test failures after the underlying accounting logic changed.
Original PR description
Adjust the FEC export test expectations to match the updated `EcritureLib` fallback logic introduced in the related community change. Related: https://github.com/odoo/odoo/pull/257242 task-5346068 Forward-Port-Of: odoo/enterprise#125684 Forward-Port-Of: odoo/enterprise#112822
Miscellaneous changes
Backport of #275640 Despite resolving the conflicts (file moved) this version also checks the python version since PyUnstable_Type_AssignVersionTag does not exists in python 3.10 To be safer, the whole logic is skipped if python < 3.13 Forward-Port-Of: odoo/odoo#277697
Original PR description
Backport of #275640 Despite resolving the conflicts (file moved) this version also checks the python version since PyUnstable_Type_AssignVersionTag does not exists in python 3.10 To be safer, the whole logic is skipped if python < 3.13 Forward-Port-Of: odoo/odoo#277697
This fixes inconsistent automated test results in Australian payroll accounting by locking certain tests to a specific date. It helps ensure payroll reporting checks remain reliable as reporting rules change over time, with no direct impact on end users.
Original PR description
The new qualifying earning rule introduced was breaking the tests that were not frozen in the past as it changed over to the new reporting code. runbot-940160 related too [11736](https://github.com/odoo/enterprise/pull/117367#event-26694075694) Forward-Port-Of: odoo/enterprise#122576
Studio report editing now keeps an empty paragraph in place when the last character is deleted. This prevents unintended layout changes and makes report editing behave more predictably for users.
Original PR description
Problem: In Studio reports, deleting the last character of a paragraph removes the entire paragraph. Cause: `cleanEmptyStructuralContainers` removes the empty paragraph because it is considered empty. Solution: Disable `cleanEmptyStructuralContainers` for reports same as website builder. Steps to reproduce: - Create a new report. - Add multiple paragraphs. - Leave one paragraph with a single character. - Delete the character. - Observe that the paragraph is removed. task-6368965 Forward-Port-Of: odoo/enterprise#124834
A flaky automated test for restaurant appointments has been corrected so it properly closes an unfinished form before ending. This helps keep quality checks stable and reduces false alarms during development.
Original PR description
The `test_appointment_kanban_view` tour test was randomly failing with the following error: `AssertionError: Tour finished with a dirty form view being open.` This occurred because the tour ended right after clearing a date field on a form, leaving the form in a "dirty" (unsaved changes) state. This commit fixes the issue by adding a final step to the tour that clicks the cancel/discard button.
Belgian POS Blackbox configurations can no longer have their POS ID changed while a session is open. This keeps active sales sessions consistent and avoids compliance or reporting issues from mid-session identifier changes.
Original PR description
Just like the Blackbox cannot be changed on a POS config with an open session, the POS ID should not be changeable either. FW of pr: https://github.com/odoo/enterprise/pull/126162
Australian payroll no longer shows an error if an employee's Tax Treatment Category is temporarily removed. This keeps employee payroll records editable and allows the correct tax code to be recalculated once the category is set again.
Original PR description
Currently, an error occurs when a user removes the Tax Treatment Category of an Australian employee. Steps to Reproduce: - Install the `l10n_au_hr_payroll` module with demo data. - Switch to an…
Currently, an error occurs when a user removes the Tax Treatment Category of an Australian employee. Steps to Reproduce: - Install the `l10n_au_hr_payroll` module with demo data. - Switch to an `Australian company`. - Open any `Employee` > `Payroll` > remove the `Tax Treatment Category` value. `UnboundLocalError: cannot access local variable 'code' where it is not associated with a value` After the [change] in selection field behavior, users can clear the value of the field. When the user removes the Tax Treatment Category value, the system computes the tax treatment code [1]. During this process, if no condition matches, the code variable is not initialized. Converting this uninitialized variable to a string [2] raises an error. This commit ensures that when the tax treatment category is not set, the tax treatment code is set to False with an early return. Since the tax treatment category is required field and compute the correct tax treatment code, once the category is set. [change]: https://github.com/odoo/odoo/pull/214422/changes/8d2a42ac419fdf7943a0c11beb8c5de6c6f85bef [1]- https://github.com/odoo/enterprise/blob/017743cbe97b629e9d9f1895b655014d4c3abbcb/l10n_au_hr_payroll/models/hr_version.py#L450-L451 [2]- https://github.com/odoo/enterprise/blob/017743cbe97b629e9d9f1895b655014d4c3abbcb/l10n_au_hr_payroll/models/hr_version.py#L515 No task ID Forward-Port-Of: odoo/enterprise#124067
This fix prevents a false collaboration error from interrupting an automated Knowledge test that does not use collaboration features. It helps keep quality checks stable so updates can move through validation without being blocked by unrelated test noise.
Original PR description
This aims to fix Runbot build error #937788 ([1]) which wasn't fully fixed by commit [2] (see error #944595 ([3])). A collaboration error was thrown during a tour which makes no use of collaboration. Commit [2] made sure the bus from the previous test didn't persist when running this tour so it doesn't interfere, but it didn't fully reset it. [1]: https://runbot.odoo.com/odoo/runbot.build.error/937788 [2]: https://github.com/odoo/enterprise/commit/a6050dd60c587d09443907bdf955805159dbdb2e [3]: https://runbot.odoo.com/odoo/runbot.build.error/944595
Brazilian fiscal reform invoices now include the required commercial export tax unit conversion factor when sent to Avalara. This helps ensure invoice tax calculations and reporting use the expected quantity conversion data, reducing validation or compliance issues.
Original PR description
This commit adds the comexTaxUnitFactor to the json sent to Avalara when sending an invoice. comexTaxUnitFactor is a factor that convert sales quantity to comexTaxUnit, its value should be the same as cbsIbsUnitFactor. opw-6396462 Forward-Port-Of: odoo/enterprise#125695
Fixed an issue where the online payment status shown on batch payments could stay stuck on the previous record when users navigated with the pager. This ensures staff see the correct signing or payment initiation status for each batch payment, reducing confusion and follow-up errors.
Original PR description
To display the `payment_online_status` field, we use a widget called `account_online_payment_refresh_button`. The issue is that the widget don't update the field value when switching from one record to another. Steps to reproduce: 1. Create 2 batch payments 2. Do a payment initiation with the first one, and sign it 3. Do another payment initiation with the second one, but don't sign it. 4. Open 1 batch, and try to switch records with the pager 5. You should see the value is not updated task-6420585 Forward-Port-Of: odoo/enterprise#126105 Forward-Port-Of: odoo/enterprise#125643
The bugfix introduced in https://github.com/odoo/odoo/commit/01d11a770f89c391f7c6a2c46a3d770d10afb428 made it so that "personal" outgoing mail servers are blocked/ignored from being used in email marketing as dedicated servers. In doing so, it missed the fact that while in *Email Marketing > Settings*, the "Dedicated Server" picker now correctly ignores personal OMS entries, the selection widget for `mail_server_id` in `view_mail_mass_mailing_form` still let's you manually select a OMS with a
Original PR description
The bugfix introduced in https://github.com/odoo/odoo/commit/01d11a770f89c391f7c6a2c46a3d770d10afb428 made it so that "personal" outgoing mail servers are blocked/ignored from being used in email…
The bugfix introduced in https://github.com/odoo/odoo/commit/01d11a770f89c391f7c6a2c46a3d770d10afb428 made it so that "personal" outgoing mail servers are blocked/ignored from being used in email marketing as dedicated servers.
In doing so, it missed the fact that while in *Email Marketing > Settings*, the "Dedicated Server" picker now correctly ignores personal OMS entries, the selection widget for `mail_server_id` in `view_mail_mass_mailing_form` still let's you manually select a OMS with an owner set. As there is not warning or an explicit error, this can lead to accidental miss configurations on an email marketing campaign, where the selected OMS will be actually ignored by the backend.
To align the changes introduced by the bugfix, we add a search domain to the selection field, so that only OMS with `('owner_user_id', '=', False)` will be presented as a choice.
OPW-6388562
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#278918
Forward-Port-Of: odoo/odoo#278595Issue caused because of https://github.com/odoo/odoo/commit/619d8ce9f31349ed06b11ead4988a4a1d9ca6bdd Steps to reproduce- Create db with demo and install l10n_in Create a new company for India (other than IN Company) Go to Settings -> Accounting/Invoice Tab -> Enable Ewaybill traceback ```py Traceback (most recent call last): File "/home/odoo/odoo18/community/odoo/orm/models.py", line 5385, in ensure_one _id, = self._ids ^^^^ ValueError: not enough values to unpack (expected
Original PR description
Issue caused because of https://github.com/odoo/odoo/commit/619d8ce9f31349ed06b11ead4988a4a1d9ca6bdd Steps to reproduce- Create db with demo and install l10n_in Create a new company for India (other…
Issue caused because of https://github.com/odoo/odoo/commit/619d8ce9f31349ed06b11ead4988a4a1d9ca6bdd Steps to reproduce-
Create db with demo and install l10n_in
Create a new company for India (other than IN Company) Go to Settings -> Accounting/Invoice Tab -> Enable Ewaybill
traceback
```py
Traceback (most recent call last):
File "/home/odoo/odoo18/community/odoo/orm/models.py", line 5385, in ensure_one
_id, = self._ids
^^^^
ValueError: not enough values to unpack (expected 1, got 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/odoo/odoo18/community/odoo/http/router.py", line 273, in __call__
response = serve_db(request)
^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/odoo/http/router.py", line 380, in serve_db
registry = Registry(request.db)
^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/odoo/orm/registry.py", line 105, in __new__
return cls.new(db_name)
^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/odoo/tools/func.py", line 67, in locked
return func(inst, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/odoo/orm/registry.py", line 217, in new
cr.rollback()
File "/home/odoo/odoo18/community/odoo/sql_db.py", line 568, in rollback
with rollbacking:
File "/home/odoo/.pyenv/versions/3.12.0/lib/python3.12/contextlib.py", line 144, in __exit__
next(self.gen)
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 1004, in rollbacking
self.restore_state()
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 1067, in restore_state
self.reset()
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 912, in reset
self._reset_registry_change()
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 832, in _reset_registry_change
registry._setup_models__(cr)
File "/home/odoo/odoo18/community/odoo/tools/func.py", line 67, in locked
return func(inst, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/odoo/orm/registry.py", line 422, in _setup_models__
env.invalidate_all()
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 395, in invalidate_all
self.flush_all()
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 413, in flush_all
self._recompute_all()
File "/home/odoo/odoo18/community/odoo/orm/environments.py", line 406, in _recompute_all
self[field.model_name]._recompute_field(field)
File "/home/odoo/odoo18/community/odoo/orm/models.py", line 6462, in _recompute_field
field.recompute(records)
File "/home/odoo/odoo18/community/odoo/orm/fields.py", line 2042, in recompute
apply_except_missing(self.compute_value, recs)
File "/home/odoo/odoo18/community/odoo/orm/fields.py", line 2012, in apply_except_missing
func(records)
File "/home/odoo/odoo18/community/odoo/orm/fields.py", line 2066, in compute_value
records._compute_field_value(self)
File "/home/odoo/odoo18/community/addons/mail/models/mail_thread.py", line 498, in _compute_field_value
return super()._compute_field_value(field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/odoo/orm/models.py", line 4387, in _compute_field_value
determine(field.compute, self)
File "/home/odoo/odoo18/community/odoo/orm/fields.py", line 82, in determine
return needle(*args)
^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/addons/l10n_in_ewaybill/models/l10n_in_ewaybill.py", line 228, in _compute_document_partners_details
seller_buyer_details = ewaybill._get_seller_buyer_details()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/addons/l10n_in_ewaybill/models/l10n_in_ewaybill.py", line 185, in _get_seller_buyer_details
return move._get_l10n_in_seller_buyer_party()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/odoo18/community/addons/l10n_in/models/account_invoice.py", line 629, in _get_l10n_in_seller_buyer_party
self.ensure_one()
File "/home/odoo/odoo18/community/odoo/orm/models.py", line 5388, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: account.move()
```
In this commit, we resolve the above traceback
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#276216To improve compliance with French requirements for FEC exports. Now we avoid exporting empty or placeholder labels ('/') by improving the fallback logic for EcritureLib. So now we, - Use existing line label when valid - For receivable/payable lines, fallback to 'partner - reference' - Otherwise fallback to move reference or name - Replace '/' with 'Balance initiale' for opening entries Related: https://github.com/odoo/enterprise/pull/112822 task-5346068 Forward-Port-Of: odoo/odoo#2786
Original PR description
To improve compliance with French requirements for FEC exports. Now we avoid exporting empty or placeholder labels ('/') by improving the fallback logic for EcritureLib. So now we,
- Use existing line label when valid
- For receivable/payable lines, fallback to 'partner - reference'
- Otherwise fallback to move reference or name
- Replace '/' with 'Balance initiale' for opening entries
Related: https://github.com/odoo/enterprise/pull/112822
task-5346068
Forward-Port-Of: odoo/odoo#278644
Forward-Port-Of: odoo/odoo#257242Issue ----- International deliveries for fractions of items (eg 500g of a product sold by kg) are rejected by Sendcloud. Steps to reproduce ----- - Setup Sendcloud - Fedex international - Create a product - weight: 1kg - valid hs code - Create a contact (outside EU if the company is in EU) - Deliver 0.5 of the product to the contact > Error "... parcel not returned from Sendcloud" Cause ----- Sendcloud returns he folloing error: > "The total weight for declared items e
Original PR description
Issue ----- International deliveries for fractions of items (eg 500g of a product sold by kg) are rejected by Sendcloud. Steps to reproduce ----- - Setup Sendcloud - Fedex international - Create a…
Issue ----- International deliveries for fractions of items (eg 500g of a product sold by kg) are rejected by Sendcloud. Steps to reproduce ----- - Setup Sendcloud - Fedex international - Create a product - weight: 1kg - valid hs code - Create a contact (outside EU if the company is in EU) - Deliver 0.5 of the product to the contact > Error "... parcel not returned from Sendcloud" Cause ----- Sendcloud returns he folloing error: > "The total weight for declared items exceeds the total weight set for the shipment." This is because the `weight` set on the shipment https://github.com/odoo/enterprise/blob/99a13453cac8a7a4677cef3df8896329c90c9e99/delivery_sendcloud/models/sendcloud_service.py#L449-L464 corresponds to the weight of the package, whereas the weight set on the description of the product in `parcel_items` corresponds to the weight of one "full" unit of the product. https://github.com/odoo/enterprise/blob/99a13453cac8a7a4677cef3df8896329c90c9e99/delivery_sendcloud/models/sendcloud_service.py#L327-L335 We cannot change the quantity in `parcel_items` to match the actual delivered one because the field should be an integer. https://sendcloud.dev/api/v2/parcels/create-a-parcel-or-parcels#body-one-of-0-parcel-parcel-items-items-quantity The price is also off, because it gets taken from the `move_line`, so it reflects the price of the actual quantity and not a "full" item. https://github.com/odoo/odoo/blob/208a8a6a5adb8ec1f2710453c2ee3b54c55a9f1e/addons/stock_delivery/models/delivery_carrier.py#L235 Note that this issue is common to **all UoM types**. Solution ----- Since we cannot change the quantity, we can instead adapt the description and weight sent in `parcel_items`. For example, sending 300g of sugar, we would send - description: "Sugar (0.3 kg)" - weight: "0.300" ----- Ticket: opw-6346330 Forward-Port-Of: odoo/odoo#277440
Description of the issue this commit addresses: When a member of the Invoicing group tries to create a payment trough the L10nPlAccountPaymentRegister wizard, upon clicking "Create Payment", an AccessError is thrown. Invoicing group members should be able to handle payments so this is an issue. --- Steps to reproduce: 1. Make sure sale_management and l10n_pl_bank_verification are installed. 2. Create a new user with "Invoicing" Accounting group. 3. Create a new sales order with sai
Original PR description
Description of the issue this commit addresses: When a member of the Invoicing group tries to create a payment trough the L10nPlAccountPaymentRegister wizard, upon clicking "Create Payment", an…
Description of the issue this commit addresses: When a member of the Invoicing group tries to create a payment trough the L10nPlAccountPaymentRegister wizard, upon clicking "Create Payment", an AccessError is thrown. Invoicing group members should be able to handle payments so this is an issue. --- Steps to reproduce: 1. Make sure sale_management and l10n_pl_bank_verification are installed. 2. Create a new user with "Invoicing" Accounting group. 3. Create a new sales order with said user (any customer, any product) 4. Confirm the quotations and, from its form view, "Create Invoice". 5. Confirm the invoice and, from its form view, "Pay". 6. Upon clicking "Create Payment", an Access Error is thrown. --- Desired behavior after this commit is merged: This commit makes sure an Invoicing group member is able to create the payment withtout AccessErrors being thrown. --- task-none feedback from: https://github.com/odoo/odoo/pull/267992 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279033 Forward-Port-Of: odoo/odoo#270008
Issue: If a product has a pricelist that updates on quantity and in quotation preview the customer changes the quantity the unit price doesn't update. Steps to reproduce: Create a product with price list that change depending on quantity. In a new quotation create a section and set it to optional. Add your product under this new section, and enter preview. Notice that if you change the quantity so that a different pricelist would apply the unit price still does not change. Cause: The va
Original PR description
Issue: If a product has a pricelist that updates on quantity and in quotation preview the customer changes the quantity the unit price doesn't update. Steps to reproduce: Create a product with price list that change depending on quantity. In a new quotation create a section and set it to optional. Add your product under this new section, and enter preview. Notice that if you change the quantity so that a different pricelist would apply the unit price still does not change. Cause: The value for unit price was not getting updated. Fix: After changing quantities update the price unit if there are active pricelists. As not all customers might want this change, it also checks for `sale.disable_sale_update`, so that the user can choose whether to update or not. opw-6377679 Forward-Port-Of: odoo/odoo#278802 Forward-Port-Of: odoo/odoo#275868
Since a cron can be manually or automatically disabled, it is interesting to track when and by who a cron a disabled or re-enabled. So we just add tracking on the active field. 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 Forward-Port-Of: odoo/odoo#279037
Original PR description
Since a cron can be manually or automatically disabled, it is interesting to track when and by who a cron a disabled or re-enabled. So we just add tracking on the active field. 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 Forward-Port-Of: odoo/odoo#279037
When refunding an order that had a fixed-amount global discount, the refunded total was inflated: e.g. a 65.00 order (80.00 - 15.00 fixed discount) was refunded as 95.00 instead of 65.00. On the refund order `amount_paid` then differed from `amount_total`, so the POS session's closing entry could not balance; `_validate_session` rolled back and no `account.move` was created, leaving the session closed with no accounting. When a refund is created, the product lines are negated and the discount
Original PR description
When refunding an order that had a fixed-amount global discount, the refunded total was inflated: e.g. a 65.00 order (80.00 - 15.00 fixed discount) was refunded as 95.00 instead of 65.00. On the…
When refunding an order that had a fixed-amount global discount, the refunded total was inflated: e.g. a 65.00 order (80.00 - 15.00 fixed discount) was refunded as 95.00 instead of 65.00. On the refund order `amount_paid` then differed from `amount_total`, so the POS session's closing entry could not balance; `_validate_session` rolled back and no `account.move` was created, leaving the session closed with no accounting. When a refund is created, the product lines are negated and the discount line is excluded, then `pos_discount` re-applies the global discount to the refund order through `applyDiscount`. For a fixed amount, `reduce_base_lines_to_target_amount` targets an absolute value and does not follow the sign of the (now negative) base, so the discount keeps the sale sign. Percentages scale with the base and are not affected. Negate the fixed discount amount when the destination order is a refund so it mirrors the negative base. The stored `discount_value` is left unchanged so the auto-resync of the discount stays idempotent. opw-6400738 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
**Current behavior before PR:** Steps to reproduce the issue: - Go to a To-Do. - Insert a heading, write something. - Insert a table of content. - Make sure that editable is not scrollable. Clicking on heading label inside toc leads to traceback. The issue occurs after merging commit [1]. When editable is not scrollable then `closestScrollableY` returns null which leads to traceback. **Desired behavior after PR:** If editable is not scrollable then clicking on heading inside to
Original PR description
**Current behavior before PR:** Steps to reproduce the issue: - Go to a To-Do. - Insert a heading, write something. - Insert a table of content. - Make sure that editable is not scrollable. Clicking on heading label inside toc leads to traceback. The issue occurs after merging commit [1]. When editable is not scrollable then `closestScrollableY` returns null which leads to traceback. **Desired behavior after PR:** If editable is not scrollable then clicking on heading inside toc should hightlight the corresponding heading without traceback. [1]: https://github.com/odoo/odoo/commit/f5cf8565e7d09edd3a29fd95537381fb70d75785 task-6405894 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277657
**Issue** A traceback is raised when creating a batch if the batch sequence prefix does not contain the expected '/' separator. **Steps to reproduce** - Go to settings > technical > sequences & identifiers > sequence: - batch transfer: - prefix: BATCH- - Create a new batch: - operation type: delivery orders - Try to save -> a traceback is triggered: ```ValueError: not enough values to unpack (expected 2, got 1)``` **Cause** `_prepare_name()` assumes that the sequence
Original PR description
**Issue**
A traceback is raised when creating a batch if the batch sequence prefix does not contain the expected '/' separator.
**Steps to reproduce**
- Go to settings > technical > sequences & identifiers > sequence:
- batch transfer: - prefix: BATCH-
- Create a new batch:
- operation type: delivery orders
- Try to save -> a traceback is triggered:
```ValueError: not enough values to unpack (expected 2, got 1)```
**Cause**
`_prepare_name()` assumes that the sequence returned by
`next_by_code()` contains a '/' separator and directly unpacks the
result of `rsplit('/', 1)`.
When no '/' is present, `rsplit()` returns a list containing a single
element, causing the unpacking to fail.
https://github.com/odoo/odoo/blob/18407651d2912b7d30463ec72cd379177530ef4f/addons/stock_picking_batch/models/stock_picking_batch.py#L418-L419
opw-6304270
Forward-Port-Of: odoo/odoo#277281
Forward-Port-Of: odoo/odoo#272212The `Quantity On Hand` field doesn't always show up directly To reproduce the issue: 1. Create a product template without any tracking 2. Switch the tracking to 'Quantity' Error: if we don't save the form, the `Quantity On Hand` field doesn't show up. That's terrible and reminds us the so old click-to-edit Odoo 14. The field `qty_available` is wrapped into a `div` container that is invisible in some conditions, and one of them is based on `is_storable`: https://github.com/odoo/odoo
Original PR description
The `Quantity On Hand` field doesn't always show up directly To reproduce the issue: 1. Create a product template without any tracking 2. Switch the tracking to 'Quantity' Error: if we don't save the…
The `Quantity On Hand` field doesn't always show up directly To reproduce the issue: 1. Create a product template without any tracking 2. Switch the tracking to 'Quantity' Error: if we don't save the form, the `Quantity On Hand` field doesn't show up. That's terrible and reminds us the so old click-to-edit Odoo 14. The field `qty_available` is wrapped into a `div` container that is invisible in some conditions, and one of them is based on `is_storable`: https://github.com/odoo/odoo/blob/913efdfe9af3d1dd75a0687a72a7ec5ecb7297fe/addons/stock/views/product_views.xml#L194-L195 The field is a computed one and will be set to `False` under some conditions in its compute method. The compute will never mark it as `True`, which is a first issue. Second, in the above use case, it only changes to `True` when saving thanks to the inverse method of the `tracking field`: https://github.com/odoo/odoo/blob/1fdc147b75b1746f85d810f1288bd1d632166083/addons/stock/models/product.py#L1003-L1005 This therefore explains why the `Quantity On Hand` doesn't show up during step 2: it's an onchange mechanism, the inverse methods are not triggered. A similar issue will also happen on a variant form, but because of another reason. This time we need to look at the field `qty_available` itself, which depends on `show_qty_update_button`: https://github.com/odoo/odoo/blob/913efdfe9af3d1dd75a0687a72a7ec5ecb7297fe/addons/stock/views/product_views.xml#L200 The field is a computed one and the method is missing one dependency. No ticket Discovered during PR review of opw-6316788
Windows nightly builds have been failing for several days with this obscure NSIS error message in Odoo 19.0: Internal compiler error #12345: error mmapping datablock to 30283637 Root cause: the accumulated size of `.po` files across all modules has grown past a threshold where the NSIS solid compressor tries to mmap a buffer larger than the ~2 GiB address space available to the 32-bit makensis running under Wine. Simply dropping the `/SOLID` option makes the build pass but nearly doubl
Original PR description
Windows nightly builds have been failing for several days with this obscure NSIS error message in Odoo 19.0: Internal compiler error #12345: error mmapping datablock to 30283637 Root cause: the…
Windows nightly builds have been failing for several days with this obscure NSIS error message in Odoo 19.0:
Internal compiler error #12345: error mmapping datablock to 30283637
Root cause: the accumulated size of `.po` files across all modules has grown past a threshold where the NSIS solid compressor tries to mmap a buffer larger than the ~2 GiB address space available to the 32-bit makensis running under Wine. Simply dropping the `/SOLID` option makes the build pass but nearly doubles the size of the final installer, which is not acceptable.
The chosen fix is to pre-bundle all `.po` files into a single solid 7z archive and extract it at install time using the `Nsis7z` plugin. This keeps the NSIS datablock well below the and yields comparable or better final installer size than the previous approach, along with faster build times.
While at it, this commit also modernizes the Windows build environment to unblock a separate wine-devel install regression that has been affecting Odoo 17.0 nightlies on Debian Bookworm.
Changes:
- Bundle `.po` files into `i18n_bundle.7z` inside the build container prior to invoking makensis; extract it at install time via the `Nsis7z` plugin.
- Bump the base image from Debian Bookworm to Trixie.
- Switch from `wine-devel` to `wine-stable`, which resolves the install regression on Bookworm-based builds.
- Upgrade NSIS to the latest release.
- Refactor the NSIS installation step to remove the hardcoded version from `package.py`.
This fix is made in Odoo 17.0 to unblock the wine-devel issue there and to benefit from the smaller installer size on supported stable branches.
Forward-Port-Of: odoo/odoo#278681
Forward-Port-Of: odoo/odoo#278378**Steps to reproduce:** * Install the **Accounting** module. * Open a **Bank Journal** and go to the **Inbound Payment Methods** tab. * Add the **Manual** payment method multiple times and give each payment method line a different name. * Go to **Customers → Payments** and create a payment using any of these payment method lines. * Print the **Payment Receipt** from the gear menu. **Observed behavior:** * The receipt always displays the **Manual** payment method name. * The custom name
Original PR description
**Steps to reproduce:** * Install the **Accounting** module. * Open a **Bank Journal** and go to the **Inbound Payment Methods** tab. * Add the **Manual** payment method multiple times and give each…
**Steps to reproduce:** * Install the **Accounting** module. * Open a **Bank Journal** and go to the **Inbound Payment Methods** tab. * Add the **Manual** payment method multiple times and give each payment method line a different name. * Go to **Customers → Payments** and create a payment using any of these payment method lines. * Print the **Payment Receipt** from the gear menu. **Observed behavior:** * The receipt always displays the **Manual** payment method name. * The custom name configured on the selected payment method line is ignored. **Cause:** * The report retrieves the payment method name from `account.payment.method`. * However, the displayed name is configured on `account.payment.method.line`, so the report always shows the generic payment method name. **Fix:** * Read the payment method name from the selected `account.payment.method.line`. * The payment receipt now displays the configured payment method line name. opw-6395829 Forward-Port-Of: odoo/odoo#277104
e39bf6c6ab31e57d472a552cb9b902496e6323ae introduced a blacklist to email sending, to filter out "alias emails" (catchall...) & the root partner email (odoobot) from being sent certain emails, such as mailings. By default, odoobot email is odoobot@example.com. However, there are cases where users will have a legitimate partner that matches the odoobot email; an example of this is saas config, which automatically changes the odoobot email to the admin email set on database spin-up. This
Original PR description
e39bf6c6ab31e57d472a552cb9b902496e6323ae introduced a blacklist to email sending, to filter out "alias emails" (catchall...) & the root partner email (odoobot) from being sent certain emails, such as mailings. By default, odoobot email is odoobot@example.com. However, there are cases where users will have a legitimate partner that matches the odoobot email; an example of this is saas config, which automatically changes the odoobot email to the admin email set on database spin-up. This prevents the database admin from receiving their own mailings. To fix this, the root partner email is now only added to the blacklist if no active partner has the same email. Steps to reproduce: - Add a mailing contact with the same email as the root partner - Send a mailing to that mailing contact task-4893615 Forward-Port-Of: odoo/odoo#278926 Forward-Port-Of: odoo/odoo#264112
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3dd56325d8 [REL] 19.3.14 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/7d7ac96719 [FIX] ui_sheet: `getCellWidth` getter for non-active sheet [Task: 6409426](https://www.odoo.com/odoo/2328/tasks/6409426) https://github.com/odoo/o-spreadsheet/commit/476b1731db [FIX] pivot: prevent drag & drop in pivot side panel [Task: 6268403](https://www.odoo.com/odoo/2328/tasks/6268
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3dd56325d8 [REL] 19.3.14 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3dd56325d8 [REL] 19.3.14 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/7d7ac96719 [FIX] ui_sheet: `getCellWidth` getter for non-active sheet [Task: 6409426](https://www.odoo.com/odoo/2328/tasks/6409426) https://github.com/odoo/o-spreadsheet/commit/476b1731db [FIX] pivot: prevent drag & drop in pivot side panel [Task: 6268403](https://www.odoo.com/odoo/2328/tasks/6268403) https://github.com/odoo/o-spreadsheet/commit/186ab9ce81 [FIX] dashboard: clickable cell is not triggered by a right click [Task: 6365823](https://www.odoo.com/odoo/2328/tasks/6365823) https://github.com/odoo/o-spreadsheet/commit/2a4f4991cb [FIX] calendar chart: skip missing value tooltips [Task: 6276800](https://www.odoo.com/odoo/2328/tasks/6276800) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> 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: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@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> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
**Steps to reproduce:** 1. Enable debug mode and add a snippet. 2. Add a YouTube video with options like autoplay enabled. 3. Double click the video or use "Replace Media". 4. A traceback occurs while reopening the video options. **Root Cause:** When the media dialog is reopened on an existing video, `syncOptionsWithUrl()` derives each switch option's value from the URL: `value = this.state.urlInput.includes(urlParameter)`, which stores Boolean `true` when e.g. autoplay is enabled.
Original PR description
**Steps to reproduce:** 1. Enable debug mode and add a snippet. 2. Add a YouTube video with options like autoplay enabled. 3. Double click the video or use "Replace Media". 4. A traceback occurs…
**Steps to reproduce:**
1. Enable debug mode and add a snippet.
2. Add a YouTube video with options like autoplay enabled.
3. Double click the video or use "Replace Media".
4. A traceback occurs while reopening the video options.
**Root Cause:**
When the media dialog is reopened on an existing video,
`syncOptionsWithUrl()` derives each switch option's value from the URL:
`value = this.state.urlInput.includes(urlParameter)`, which stores
Boolean `true` when e.g. autoplay is enabled. Similarly, toggling an
enabled option off stores Boolean `false`
The `value` prop was already `Boolean` but after commit https://github.com/odoo/odoo/commit/ae894892e048b
we declared the prop as `value: { type: String, optional: true }` on
`VideoOption`. In debug mode, OWL validates props and throws
"Invalid props for component 'VideoOption': 'value' is not a string"
when it receives those booleans. The declaration does not match the
values the component actually receives.
**Fix:**
Normalizing the state to strings at the source would require rewriting
the option-state logic for no behavioral gain. Since booleans are
produced deliberately by two code paths, the honest prop type for value
is `[String, Boolean]`.
task-6233423
Forward-Port-Of: odoo/odoo#266304While preloading chart template data, if an account already exists in the db but has `active=False`, it is not found because archived records are excluded from the [`_search`]. As a result, the load attempts to create a new account. During creation, the Python constraint [`_ensure_code_is_unique`] searches with `active_test=False`, finds the archived account with the same code, and raises a ValidationError: ```py File "/home/odoo/src/odoo/saas-19.2/addons/account/models/chart_template.py"
Original PR description
While preloading chart template data, if an account already exists in the db but has `active=False`, it is not found because archived records are excluded from the [`_search`]. As a result, the load…
While preloading chart template data, if an account already exists in the db but has `active=False`, it is not found because archived records are excluded from the [`_search`].
As a result, the load attempts to create a new account. During creation, the Python constraint [`_ensure_code_is_unique`] searches with `active_test=False`, finds the archived account with the same code, and raises a ValidationError:
```py
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/chart_template.py", line 735, in _load_data
'noupdate': True,
^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 4519, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 4426, in _load_records_create
records = self.create(vals_list)
^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/decorators.py", line 363, in create
return method(self, vals_list)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_account.py", line 1057, in create
records._ensure_code_is_unique()
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_account.py", line 1135, in _ensure_code_is_unique
raise ValidationError(
odoo.exceptions.ValidationError: Account codes must be unique. You can't create accounts with these duplicate codes: 1.1.1.02.003, 1.1.1.02.004
```
Steps to reproduce:
- In a `v19.0` database, install `l10n_ar` with demo data.
- The accounts with codes `1.1.1.02.003` and `1.1.1.02.004` are created by [`_create_outstanding_accounts`].
- Archive those accounts and upgrade to `v19.2`.
- During the upgrade, [`_get_latam_check_outstanding_account_account`] attempts to create new accounts with the same codes, triggering the duplicate code validation.
tbg-2840
[`_search`]: https://github.com/odoo/odoo/blob/619d8ce9f31349ed06b11ead4988a4a1d9ca6bdd/addons/account/models/chart_template.py#L438
[`_ensure_code_is_unique`]: https://github.com/odoo/odoo/blob/19.0/addons/account/models/account_account.py#L1133
[`_create_outstanding_accounts`]: https://github.com/odoo/odoo/blob/06a46b083fde5688d71c5602553316c9e7160b6a/addons/account/models/chart_template.py#L925C9-L949
[`_get_latam_check_outstanding_account_account`]: https://github.com/odoo/odoo/blob/saas-19.2/addons/l10n_latam_check/models/account_chart_template.py#L60-L76
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279313
Forward-Port-Of: odoo/odoo#279092# How to reproduce - Go to a website page - Add atleast one image to the page - Go to Site > Optimize SEO - Add a description to an image - Save # The issue The description is not applied to the image. It is not present in the image's alt in the page and if we re-open the SEO modal, it is not there either. # Cause This [PR] changed the way the image's id are generated in `get_alt_image()`, but did not change the id generation in the check done in `update_alt_images()`, so this check
Original PR description
# How to reproduce - Go to a website page - Add atleast one image to the page - Go to Site > Optimize SEO - Add a description to an image - Save # The issue The description is not applied to the image. It is not present in the image's alt in the page and if we re-open the SEO modal, it is not there either. # Cause This [PR] changed the way the image's id are generated in `get_alt_image()`, but did not change the id generation in the check done in `update_alt_images()`, so this check always fails: https://github.com/odoo/odoo/blob/36eee85dbaed927ff76b2d44a44ba476e9588c72/addons/website/controllers/main.py#L894 [PR]: https://github.com/odoo/odoo/commit/1f1980a1d9835567597ca239d404f47d4677dc47 # Proposed solution Added an helper function for the id generation. This is not necessary but might prevent this from happening again, up to the reviewer to keep it or not opw-6389523 Forward-Port-Of: odoo/odoo#278675 Forward-Port-Of: odoo/odoo#277588
Steps to produce: 1) Install Manufacturing & enable "Work Order Dependencies" in the settings 2) Make a new BOM with 2 operations 3) Check "Operation Dependencies" in the miscellaneous tab on the BOM's form view. 4) Configure the first sequential operation to be blocked by the second 5) Make and confirm an MO using this BOM 6) Uncheck "Operation Dependencies" on the BOM 7) Press "Plan" on the MO, a validation error is thrown stating "You cannot create cyclic dependency." Issue occur
Original PR description
Steps to produce: 1) Install Manufacturing & enable "Work Order Dependencies" in the settings 2) Make a new BOM with 2 operations 3) Check "Operation Dependencies" in the miscellaneous tab on the…
Steps to produce: 1) Install Manufacturing & enable "Work Order Dependencies" in the settings 2) Make a new BOM with 2 operations 3) Check "Operation Dependencies" in the miscellaneous tab on the BOM's form view. 4) Configure the first sequential operation to be blocked by the second 5) Make and confirm an MO using this BOM 6) Uncheck "Operation Dependencies" on the BOM 7) Press "Plan" on the MO, a validation error is thrown stating "You cannot create cyclic dependency." Issue occurs because after the MO is confirmed the blocked_by_workorder_ids field for mrp.workorder records is set based on the order manually configured on the BOM (operation 1 is blocked by operation 2). After the BOM is edited to have allow_operation_dependencies = false, then Odoo uses the default sequential ordering when planning the operations (operation 2 is blocked by operation 1). Since the old ordering is never cleared, a cycle is created unintentionally. This PR resolves this issue by clearing the blocked_by_workorder_ids field on mrp.workorder records. opw-6334271 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278255 Forward-Port-Of: odoo/odoo#275154
Problem: Changing the text alignment of a table header in Studio reports has no effect. Cause: When the alignment is already defined by a CSS class using `!important` (for example, `text-center`), the inline style applied from the toolbar is ignored. Solution: Backport commit 373be20905bcb11f8323a986053e3dc7996ce567. Steps to reproduce: - Open the invoice report. - Change the alignment of a table header. - Observe that the new alignment is not applied. opw-6389158 --- I con
Original PR description
Problem: Changing the text alignment of a table header in Studio reports has no effect. Cause: When the alignment is already defined by a CSS class using `!important` (for example, `text-center`), the inline style applied from the toolbar is ignored. Solution: Backport commit 373be20905bcb11f8323a986053e3dc7996ce567. Steps to reproduce: - Open the invoice report. - Change the alignment of a table header. - Observe that the new alignment is not applied. opw-6389158 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277922 Forward-Port-Of: odoo/odoo#276470
Problem: Clicking an image padding option in Studio reports closes the dropdown, but the selected option is not applied. Cause: When editing inside an `iframe`, `unFocusEditable` is triggered on `focusin`, which runs `selection_leave_handlers` and closes the dropdown before the `click` event can propagate. Solution: Add `data-prevent-closing-overlay="true"` to the image padding dropdown, as done for other dropdowns, so it remains open until the click event is handled. Steps to reprod
Original PR description
Problem: Clicking an image padding option in Studio reports closes the dropdown, but the selected option is not applied. Cause: When editing inside an `iframe`, `unFocusEditable` is triggered on `focusin`, which runs `selection_leave_handlers` and closes the dropdown before the `click` event can propagate. Solution: Add `data-prevent-closing-overlay="true"` to the image padding dropdown, as done for other dropdowns, so it remains open until the click event is handled. Steps to reproduce: - Open a new report. - Add an image. - Select the image. - Open the padding dropdown. - Click a padding option. - Observe that the dropdown closes but the padding is not applied. task-6368964 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279263 Forward-Port-Of: odoo/odoo#276448
odoo/odoo#155588 was a workaround to the lack of location permissions in the iOS app, skipping geolocation entirely for check in/out. Since odoo/mobile#118 added support for them, we can now revert that fix so iOS users get prompted for their location again. task-6279460 Forward-Port-Of: odoo/odoo#278685 Forward-Port-Of: odoo/odoo#276934
Original PR description
odoo/odoo#155588 was a workaround to the lack of location permissions in the iOS app, skipping geolocation entirely for check in/out. Since odoo/mobile#118 added support for them, we can now revert that fix so iOS users get prompted for their location again. task-6279460 Forward-Port-Of: odoo/odoo#278685 Forward-Port-Of: odoo/odoo#276934
When displaying lots or serial numbers on invoices, the quantity and UoM were rendered without any separator in the SN/LN table, e.g. `1.00Units`. - Add a non-breaking space between the quantity and UoM so the table renders as `1.00 Units`. - Also align the SN/LN value cell consistently with its right-aligned column header. - Update the `sale_stock` and `sale_mrp` report tests to expect whitespace between the quantity and UoM in the rendered invoice output. Task [link](https://www.odoo.
Original PR description
When displaying lots or serial numbers on invoices, the quantity and UoM were rendered without any separator in the SN/LN table, e.g. `1.00Units`. - Add a non-breaking space between the quantity and UoM so the table renders as `1.00 Units`. - Also align the SN/LN value cell consistently with its right-aligned column header. - Update the `sale_stock` and `sale_mrp` report tests to expect whitespace between the quantity and UoM in the rendered invoice output. Task [link](https://www.odoo.com/odoo/project/967/tasks/6365178) task-6365178 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279214 Forward-Port-Of: odoo/odoo#274660