Tuesday, May 19, 2026
18 changes · saas-19.2
Enhancements to existing features
This update ensures the "Save Order" button remains consistently available for users. This allows them to seamlessly save their order progress and resume it later, regardless of the device they're using within the same session. This improves the user experience and reduces frustration when working with point-of-sale orders.
Original PR description
The "Save Order" button is now always available, allowing users to easily save and resume their orders on different devices within the same session. task-id: 5966678 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261809 Forward-Port-Of: odoo/odoo#250405
Resolved issues and error corrections
This update ensures Odoo correctly sets the `toStateCode` field for SEZ transactions when generating e-waybills. Previously, this was missing, causing API errors. Now, the system automatically sets it to 99, guaranteeing compliance with e-waybill regulations and preventing disruptions to export transactions.
Original PR description
For SEZ transactions, the e-waybill API requires `toStateCode` to be set to 99. Previously, this value was not enforced, leading to API errors: - 373 for export transactions - 641 for supply and CKD/SKD/lots supply This fix updates the logic to derive `toStateCode` based on the invoice's GST treatment. When the transaction is identified as SEZ, `toStateCode` is correctly set to 99, ensuring compliance with e-waybill requirements and preventing API failures. task-6117694 Forward-Port-Of: odoo/odoo#259327
This update resolves an issue where attachments without specific data caused crashes in Odoo's image processing. The fix ensures that when attachment data is missing, a blank bytes object is used instead, preventing errors and maintaining proper image handling. This improves the stability of features relying on attachments.
Original PR description
When an attachment has neither `store_fname` nor `db_datas`, the computed `raw` field was being assigned `False`. This caused crashes in flows expecting binary content, where `binary_to_image()`…
When an attachment has neither `store_fname` nor `db_datas`, the computed `raw` field was being assigned `False`.
This caused crashes in flows expecting binary content, where `binary_to_image()` ultimately passes the value to `io.BytesIO()`, which requires bytes-like data.
Traceback:
```python
Traceback (most recent call last):
File "/tmp/tmpufuj48vj/migrations/base/tests/test_mock_crawl.py", line 344,
in crawl_menu self.mock_action(action_vals)
File "/tmp/tmpufuj48vj/migrations/base/tests/test_mock_crawl.py", line 357,
in mock_action return self.mock_act_window(action)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/tmpufuj48vj/migrations/base/tests/test_mock_crawl.py", line 517,
in mock_act_window mock_method(model, view, fields_list, domain, group_by)
File "/tmp/tmpufuj48vj/migrations/base/tests/test_mock_crawl.py", line 550,
in mock_view_form [data] = record.read(fields_list)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 2734, in read
self._origin.fetch(fields)
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 3065, in fetch
fetched.mapped(field_name)
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 5477, in mapped
return [getter(record) for record in records]
^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/fields.py", line 1793, in
__get__ self.compute_value(recs)
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/fields.py", line 1964,
in compute_value records._compute_field_value(self)
File "/home/odoo/src/odoo/saas-19.2/addons/mail/models/mail_thread.py",
line 495, in _compute_field_value return super()._compute_field_value(field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 4269,
in _compute_field_value determine(field.compute, self)
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/fields.py", line 82,
in determine return needle(*args)
^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/social_instagram/models/
social_post_template.py", line 57, in _compute_instagram_preview
faulty_images, error_code = post._get_instagram_image_error()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/social_instagram/models/
social_post_template.py", line 108, in _get_instagram_image_error
image = binary_to_image(jpeg_image.with_context(bin_size=False).raw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/tools/image.py", line 428,
in binary_to_image return Image.open(io.BytesIO(source))
^^^^^^^^^^^^^^^^^^
TypeError: a bytes-like object is required, not 'bool'
```
To prevent this, fallback to an empty bytes object (`b''`) when `db_datas` is falsy during `_compute_raw`.
[here]: https://github.com/odoo/enterprise/blob/saas-19.2/social_instagram/models/social_post_template.py#L108
upg-4247928
opw-6181262
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-prThis update resolves an issue where kitchen tickets were incorrectly printed when cancelling platform orders in Odoo PoS. Now, cancelled platform orders will no longer trigger kitchen ticket printing, ensuring accurate order management and preventing unnecessary printing costs. This improves the reliability of the platform order process.
Original PR description
This fixes platform orders should not send to kitchen printer when the platform orders being cancelled. Currently accepting platform orders will not send to kitchen printer. However when cancelling platform orders on either provider platform, or within Odoo PoS. It will print a kitchen ticket of customer note. task-6071740 Forward-Port-Of: odoo/enterprise#114171
This update resolves an issue where employees archived through HR wouldn't be properly checked out from attendance. The fix utilizes a 'sudo' method to grant necessary permissions during archiving, ensuring attendance checkout occurs regardless of user roles. It also addresses a related planning access error during employee archiving.
Original PR description
- Attendance checkout - Step to reproduce: with attendance installed and an employee checked in, archive that employee by HR user. If missing attendance rights, the employee will be archived but not…
- Attendance checkout
- Step to reproduce: with attendance installed and an employee checked in, archive that employee by HR user. If missing attendance rights, the employee will be archived but not checked out from its ongoing attendance.
- Cause: if no role set for Attendance (default), no permission to update the employee attendance while archiving.
- Solution: using sudo method so that any user with sufficient rights to archive an employee, can trigger check out of the corresponding attendance.
- Planning access error (fixed in 18.0 by https://github.com/odoo/odoo/pull/219395)
- Step to reproduce: with attendance and planning installed, archive an employee having planning slots. If missing planning rights, an access error is raised
- Cause: on employee archive, the corresponding planning.slots are updated and some fields recomputed with insufficient rights.
- Solution: using sudo method for recompute.
Task: 6131692
Forward-Port-Of: odoo/odoo#264518
Forward-Port-Of: odoo/odoo#260566This update resolves a bug where duplicating a meeting tab would cause the remote tab to crash when the host ended the call. The fix ensures that call action elements handle call disappearances gracefully, preventing errors and maintaining the existing user interface.
Original PR description
**Steps to Reproduce:** - Start a new meeting (Host Tab). - Duplicate the tab or open the same meeting URL in another tab (remote tab). - In the remote tab, open the call menu (dropdown). - From the…
**Steps to Reproduce:** - Start a new meeting (Host Tab). - Duplicate the tab or open the same meeting URL in another tab (remote tab). - In the remote tab, open the call menu (dropdown). - From the host tab, disconnect/end the call. - Crashes on Remote Tab. **Current behavior before PR:** Before this PR, duplicating a meeting tab could leave the remote tab with a stale call action dropdown after the host ended the call. Since some action properties and handlers still assumed that selfSession and channel were always available, interacting with the dropdown could crash with errors. **Desired behavior after PR is merged:** After this PR, call action labels/classes defensively tolerate missing selfSession or channel references, and stale click handlers gracefully no-op when the call disappears mid-interaction. This prevents remote tab crashes during call teardown while preserving the existing UI behavior. task-[6191740](https://www.odoo.com/odoo/project/1519/tasks/6191740) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264989
This update corrects an issue where invoices using a specific tax category ('O-service out of tax scope') in Odoo failed Peppol validation. The fix ensures correct handling of this tax category, preventing validation errors and ensuring compliance with Peppol standards. This improves integration with Peppol networks.
Original PR description
**PROBLEM** In peppol, there is a tax category 'O-service out of tax scope'. This tax category is used when what is invoice can't be tax (out of the tax scope). This is different from tax exemption: when using tax category O, there can't be any vat id on the invoice. This also means you can't use tax category O with other taxes, since other taxes need the vat id. Invoices generated by odoo with tax category O failed peppol validation. **STEP TO REPRODUCE** 1. install account_edi_ubl_cii_tax_extension. 2. Create a tax with tax category O. 3. Create an invoice and try validating using the file validator. 4. You should have error BR-O-02 and BR-O-05. opw-6012669 Forward-Port-Of: odoo/odoo#264081 Forward-Port-Of: odoo/odoo#254645
This update fixes an issue where tax return entries incorrectly included all tax amounts, regardless of the specific tax return type. Previously, tax returns for regions like Manitoba were generating entries with incorrect tax calculations. This change ensures that tax return entries accurately reflect the taxes due for the specific region, improving tax reporting accuracy.
Original PR description
Issue: Validating a tax return creates an entry with all the tax aml from the company instead of filtering them according to the tax return type. Steps to reproduce: - In a company in Canada - Invoice a Customer from British Columbia in the previous month (A) - Confirm - Go to tax report -> Return - Review and Validate tax return for "Manitoba PST Return (CA)" for month A - Click on the 3 dots -> View Entry Current Behavior: - Entry has lines for PST in British-Columbia and GST taxes Expected behavior: - Entry has lines for PST in Manitoba only Cause: https://github.com/odoo/enterprise/pull/98158 introduces method `_get_vat_closing_entry_additional_domain` in the wrong class. opw-6065838 Forward-Port-Of: odoo/enterprise#116813 Forward-Port-Of: odoo/enterprise#116366
This update fixes a rounding error in the calculation of prepaid taxes for invoices in Saudi Arabia. The previous calculation was leading to inaccurate tax amounts, particularly when using global rounding. This change ensures accurate tax calculations for downpayment invoices, improving financial reporting.
Original PR description
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each…
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each with 15% taxes (triggers rounding precision issues) - Create and confirm 100% downpayment invoice - Deliver, then create final invoice with downpayment lines - Call `_l10n_sa_get_prepaid_amount()` on final invoice > Tax amount was calculated as 35.67 instead of correct 35.64 ### Cause of Issue: The prepaid amount calculation was summing pre-rounded `tax_amount_currency` values from individual downpayment lines (4.45 + 4.46 + 4.46... = 35.67), instead of summing unrounded `raw_tax_amount_currency` values (4.455 × 8 = 35.64) to calculate `tax_amount`. https://github.com/odoo/odoo/blob/27930ae41a5f03bd499983109de7f632472c3650/addons/l10n_sa_edi/models/account_edi_xml_ubl_21_zatca.py#L227-L240 This violates Odoo's [recent change](https://github.com/odoo/odoo/pull/180062) in `round_globally` pattern which states: https://github.com/odoo/odoo/blob/8a88756bed194910bc5a47e93f0e29610dbeee1f/addons/account/models/account_tax.py#L2208 ### Fix: Ensure cumulative rounding errors are avoided and correct global rounding is applied. opw-5881564 Forward-Port-Of: odoo/odoo#264713 Forward-Port-Of: odoo/odoo#261278
This update resolves an issue where dragging events with open popovers was impossible. The fix ensures that the popover closes automatically during a drag, allowing users to seamlessly move events. It also eliminates popover flickering that occurred during the drag-and-drop process.
Original PR description
[FIX] web: fix event drag and drop with opened popover Fix impossible event drag and drop when the event has its popover opened. On drag start, the popover should close to allow dragging the event. [FIX] web,calendar: fix popover flicker on event drag Fix the popover flickering when drag and dropping an event with its popover opened. Task-5965017 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264347
This update fixes an issue where invoices generated for non-Polish customers incorrectly included the country code in the VAT number field. The change ensures the correct VAT number format is used for KSeF compliance, preventing potential errors when submitting invoices to the tax authorities. This ensures accurate and compliant e-invoicing.
Original PR description
Currently, an incorrect VAT format is used in the generated `FA3 XML` for non-Polish partners, where the VAT number includes the country code. **Steps to reproduce:** - Install the `l10n_pl_edi`…
Currently, an incorrect VAT format is used in the generated `FA3 XML` for non-Polish partners, where the VAT number includes the country code. **Steps to reproduce:** - Install the `l10n_pl_edi` module and switch to a `PL Company`. - Go to Settings and enable `Allow KSeF integration` (refer to [1]). - Create and confirm an invoice for a customer (e.g., Azure Interior). - Send the invoice using `by KSeF (e-Faktura)`. **Observation:** In the generated XML file, the `NrID` field contains the VAT number `with the country code` for non-Polish partners. **Root Cause:** At [2], `get_vat_number` sets the VAT number using `compact` from `stdnum.pl.nip`, which only works for Polish VAT numbers. At [3], `get_vat_number` correctly formats Polish VAT numbers without the country code in the `if condition`. However, in the fallback (else) case, it returns the VAT number as it is, including the country code. **Fix:** This commit ensures that for non-Polish VAT numbers, the country code is removed before setting the `NrID` or `NrVatUE` values in the XML, aligning the format with KSeF requirements. Ref: https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf (Page no.: 19) [1]: https://www.odoo.com/mail/message/1057847327 [2]: https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/l10n_pl_edi/models/account_move.py#L257 [3]: https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/l10n_pl_edi/data/fa3_template.xml#L67-L82 opw-6120118 Forward-Port-Of: odoo/odoo#263081
This update resolves an issue where undoing a template conversion prevented users from creating new templates from the same project. The fix ensures that the original project's documents are properly restored and cleaned up after an undo, allowing for seamless template creation again. This improves the user experience and avoids frustrating errors.
Original PR description
Steps to Reproduce: --- 1. Create a new project. 2. Convert it into a template. 3. Click on "Undo". 4. Try to convert the project into a template again. Issue: --- After undoing the template…
Steps to Reproduce: --- 1. Create a new project. 2. Convert it into a template. 3. Click on "Undo". 4. Try to convert the project into a template again. Issue: --- After undoing the template conversion, the project's original documents folder remained archived while the template's documents folder stayed active. This inconsistent state prevented subsequent template creation from the same project. Current behaviour: --- A UserError is raised: "You cannot duplicate document(s) in the Trash." Expected behaviour: --- Undoing the template conversion should properly restore the original project's documents folder to active state and clean up the template's documents folder, allowing template conversion again without document folder conflicts. Fix: --- - Archive original project's documents folder during template creation to prevent mixed active/inactive states during copy operations - Implement callback system to properly unarchive original project's documents folder during undo task-4916027 Forward-Port-Of: odoo/odoo#264429 Forward-Port-Of: odoo/odoo#223152
This update corrects a bug that prevented users from recreating templates after undoing a previous conversion. The fix ensures that project documents are properly archived and cleaned up during the undo process, resolving a user error and allowing for seamless template management. This improves the reliability of the template creation workflow.
Original PR description
Steps to Reproduce: --- 1. Create a project with documents. 2. Convert it into a template. 3. Click on "Undo". 4. Try to convert the project into a template again. Issue: --- After undoing the template conversion, the project's original documents folder remained archived while the template's documents folder stayed active. This inconsistent state prevented subsequent template creation from the same project. Current behaviour: --- A UserError is raised: "You cannot duplicate document(s) in the Trash." Expected behaviour: --- Undoing template conversion should properly restore original project's documents folder and clean up template's documents folder. Fix: --- - Archive original project's documents folder during template creation - Implement documents folder unarchival during undo operations task-4916027 Forward-Port-Of: odoo/enterprise#117303 Forward-Port-Of: odoo/enterprise#91595
This update corrects a problem where the ABA file generated for Australian payroll wasn't being created correctly. The fix ensures the payslip batch is assigned before payment validation, guaranteeing the ABA file contains accurate payment information. This resolves a previous issue and improves the reliability of payroll reporting.
Original PR description
Payslip batch needs to be assgned before the payment batch is validated, otherwise the ABA file will be blank. This commit ensures that flow and the test ensure both aba flows generate the same file content. task-6123029 Forward-Port-Of: odoo/enterprise#116907 Forward-Port-Of: odoo/enterprise#114970
This update fixes an issue where the bank statement import process could fail due to incorrect journal selections. The system now automatically validates currency and IBAN matches, ensuring the correct journal is used and preventing user errors. This improves the reliability and accuracy of importing bank statements.
Original PR description
Behavior before: The import flow could crash with an "Expected singleton" error if multiple journals shared an IBAN. Additionally, the system blindly accepted the current context ('self') as the…
Behavior before:
The import flow could crash with an "Expected singleton" error if multiple
journals shared an IBAN. Additionally, the system blindly accepted the
current context ('self') as the target journal, even if its currency or
bank account mismatched the statement, often leading to avoidable
UserErrors.
Behavior after:
The system now validates 'self' against the statement's currency and IBAN
before assignment. If a mismatch is found, it automatically searches for
the correct journal. The search is now restricted by currency and includes
a limit=1 to prevent crashes and ensure accurate selection.
Root Cause:
In _find_additional_data(), 'journal = self' was assigned without validation.
Furthermore, the fallback search lacked a record limit and currency matching
logic, allowing multiple records to be returned when duplicates or
multi-currency setups existed.
Fix:
- Added validation for the initial 'self' candidate (currency and IBAN match).
- Refined the search domain to include currency matching (journal or
company fallback).
- Added limit=1 to the search to guarantee a singleton recordset.
opw-5462037
Forward-Port-Of: odoo/enterprise#117376
Forward-Port-Of: odoo/enterprise#115475This update optimizes a key calculation within our MRP subcontracting process, specifically when determining lead times for order points. By preventing unnecessary database queries, the change significantly reduces processing time, particularly when dealing with a large number of order points. This results in a faster and more responsive system for users.
Original PR description
When computing `qty_to_order` 1-3 extra queries are made by `get_lead_days()`, which can cause performance issues when computing `qty_to_order` for a large number of orderpoints. This commit aims to…
When computing `qty_to_order` 1-3 extra queries are made by `get_lead_days()`, which can cause performance issues when computing `qty_to_order` for a large number of orderpoints. This commit aims to prevent these extra queries by returning early if the current product is not associated with a bom. The amount this commit speeds up the compute depends on how many of products passed into `_get_lead_days()` are associated with a bom. `qty_to_order` is no longer a stored field after this commit: https://github.com/odoo/odoo/pull/159432 This benchmark was done in 18.0 on /stock.warehouse.orderpoint/search_panel_select_range. This call does not trigger the compute on all orderpoints in 17.0 as the field is stored but calling the compute directly on all orderpoints results in the same speed up as seen in 18.0. | Orderpoints | % of products linked to a bom | Time before | Queries before | Time after | Queries After | |-------------|-------------------------------|-------------|----------------|------------|---------------| | 800 | 50% | 2.8s | 1570 | 2.3s | 818 | | 8,000 | 0% | 28.2s | 16,698 | 15.3s | 242 | | 8,000 | 25% | 29.6s | 16,833 | 19.2s | 4497 | | 8,000 | 50% | 29.8s | 16,925 | 23.2s | 8693 | | 8,000 | 75% | 31.6s | 16,949 | 27.6s | 12827 | Forward-Port-Of: odoo/odoo#262321
This update fixes a bug that allowed users to create multiple leave requests for the same day, even after previously approving and rejecting a request. The fix ensures that the system accurately detects and prevents conflicting leave entries, improving data integrity and reducing potential errors in time-off management. This change was made as part of a broader effort to enhance the reliability of the HR module.
Original PR description
Steps to reproduce:- - Navigate to Time off Dashboard calendar view. - Create a leave. First approve it then refuse it. - Now on the same day create a leave and approve it. - Now re-approve the…
Steps to reproduce:- - Navigate to Time off Dashboard calendar view. - Create a leave. First approve it then refuse it. - Now on the same day create a leave and approve it. - Now re-approve the previously refused leave from step 2. - System will let user to create 2 leave of same types on same day! Cause:- In `_compute_dashboard_warning_message`, refused/cancelled leaves were excluded from warning computation. When approving a refused request, the warning message was not set, allowing the constraint check to pass even when conflicting approved requests existed for the same period. Fix:- 1. Refactored `_compute_dashboard_warning_message` to only compute warnings for active leaves (non-refused/cancelled) while still detecting conflicts with already approved requests 2. Updated `_check_date` constraint to skip validation for refused/ cancelled leaves, but enforce it when state changes to validate 3. Added 'state' to constraint triggers to ensure validation runs when approving previously refused requests task-[6181717](https://www.odoo.com/odoo/project/1251/tasks/6181717) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265038 Forward-Port-Of: odoo/odoo#262703
This update optimizes a key process in Odoo's accounting and sales modules for Vietnam (l10n_in). The change eliminates a redundant database query, significantly speeding up import operations and improving overall system performance. This avoids unnecessary data scanning, leading to faster invoice processing.
Original PR description
There is no need to do a query to get a random foreign state. This search can be performed many times during imports. While the query is generally not reading a lot of data, it is still doing a seq…
There is no need to do a query to get a random foreign state. This search can be performed many times during imports.
While the query is generally not reading a lot of data, it is still doing a seq scan because of the ORDER BY, while the query can be avoided completely.
```sql
EXPLAIN ANALYZE
SELECT "res_country_state"."id"
FROM "res_country_state"
WHERE "res_country_state"."code" NOT IN ('IN')
ORDER BY "res_country_state"."code", "res_country_state"."id"
LIMIT 1;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Limit (cost=84.93..84.94 rows=1 width=8) (actual time=0.450..0.450 rows=1 loops=1)
-> Sort (cost=84.93..90.49 rows=2224 width=8) (actual time=0.449..0.449 rows=1 loops=1)
Sort Key: code, id
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on res_country_state (cost=0.00..73.81 rows=2224 width=8) (actual time=0.012..0.281 rows=2223 loops=1)
Filter: ((code)::text <> 'IN'::text)
Rows Removed by Filter: 2
Planning Time: 0.075 ms
Execution Time: 0.462 ms
```
This can be worse if when the table is not in the buffer.
Forward-Port-Of: odoo/odoo#265007