Friday, August 7, 2026
9 changes · saas-19.2
Resolved issues and error corrections
This fix ensures that Tyro card surcharge fees are added to a point-of-sale order before the order is validated. It prevents occasional missing surcharge lines during checkout, helping businesses keep payment totals accurate.
Original PR description
Currently when completing a Tyro payment with a surcharge fee in some cases there is a race condition preventing the surcharge line to be added to the pos order before its validation This PR fixes that issue opw-6402191 Forward-Port-Of: odoo/enterprise#126035 Forward-Port-Of: odoo/enterprise#125852
The EPF Summary report now calculates EPS contributions using the employee's Basic Salary, capped at ₹15,000, instead of using the EPF amount. This helps Indian payroll teams produce more accurate statutory contribution reports and reduces compliance reporting errors.
Original PR description
**Steps to Reproduce** - Create an Indian employee. - Create a payslip for this employee. - Go to **Payroll > Reporting > EPF-ECR Report**. - Create a new report with the report type **EPF Summary**. **Before This Commit** - For the EPS contribution, we were calculating `min(15,000, EPF)` and then applying **8.33%** to the resulting amount. - This resulted in an incorrect EPS contribution amount. **After This Commit** - According to Indian payroll rules, the EPS contribution is calculated as 8.33% of `min(15,000, Basic Salary)`, rather than `8.33% of the EPF amount`. - This commit corrects the EPS contribution calculation accordingly. Task: [6442399](https://www.odoo.com/odoo/project/1251/tasks/6442399)
Dutch SBR tax return exports now use the Tax Unit VAT number when a Tax Unit is selected, instead of incorrectly using the company's Omzetbelastingnummer. This prevents rejected filings for fiscal unity registrations while keeping the company OB-number fallback for single-company filings.
Original PR description
**Steps to reproduce:** * Install the **Netherlands - SBR** (`l10n_nl_reports_sbr`) and **Netherlands - SBR OB Nummer** (`l10n_nl_reports_sbr_ob_nummer`) modules. * Create two companies with Dutch…
**Steps to reproduce:** * Install the **Netherlands - SBR** (`l10n_nl_reports_sbr`) and **Netherlands - SBR OB Nummer** (`l10n_nl_reports_sbr_ob_nummer`) modules. * Create two companies with Dutch localization. * Go to **Accounting → Configuration → Tax Units** and create a Tax Unit with its own **Tax ID** (e.g. `NL826317558B01`), adding both companies. * On the main company form, fill in the **Omzetbelastingnummer** field (e.g. `123456782B90`). * Go to **Accounting → Reporting → Tax Return**, select the Tax Unit in the filter, and click **XBRL → Download XBRL File**. **Observed behavior:** * The `<xbrli:identifier>` in the exported XBRL file contains the company's **Omzetbelastingnummer** (`123456782B90`) instead of the Tax Unit's VAT (`826317558B01`). * The tax authority rejects the return because the identifier does not match the fiscal unity registration. **Cause:** * `_get_sbr_identifier()` in `l10n_nl_reports_sbr_ob_nummer` unconditionally returns `self.env.company.l10n_nl_reports_sbr_ob_nummer` before consulting the Tax Unit. * The `super()` call, which correctly routes to `tax_unit.vat` via `report.get_vat_for_export()`, is only reached when the company field is empty — so the Tax Unit's VAT is never used when a company OB-number is set. **Fix:** * When a Tax Unit is active in the report options, delegate immediately to `super()._get_sbr_identifier()`, which resolves `tax_unit.vat` through the existing `get_vat_for_export()` logic. * The company-level `l10n_nl_reports_sbr_ob_nummer` override is preserved as a fallback for the `company_only` (no Tax Unit) case. opw-6350840 Forward-Port-Of: odoo/enterprise#126999 Forward-Port-Of: odoo/enterprise#125167
Instagram post syncing now handles posts that do not include a media link, instead of failing with an error. This prevents Social Marketing auto-sync from being blocked and avoids traceback errors when users open the app.
Original PR description
The fix introduced in https://github.com/odoo/enterprise/commit/9e9c99712ad4b9d58dc7601da41a852e457ad097 didn't account for the fact that `post.get('media_url') ` could return a None value, which in…
The fix introduced in https://github.com/odoo/enterprise/commit/9e9c99712ad4b9d58dc7601da41a852e457ad097 didn't account for the fact that `post.get('media_url') ` could return a None value, which in turn would raise en error when trying to concatenate the value later.
This in turn:
- will block syncing of instagram instagram posts
- will raise a traceback when you open the Social Marketing module and the auto-sync kicks in.
### Example traceback
```
Traceback (most recent call last):
[...]
File "/home/odoo/src/enterprise/saas-19.2/social_instagram/models/social_stream.py", line 86, in _fetch_stream_data
return self._fetch_instagram_posts()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/social_instagram/models/social_stream.py", line 64, in _fetch_instagram_posts
values['message'] = (values['message'] + "\n" + post.get('media_url')).strip()
~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
TypeError: can only concatenate str (not "NoneType") to str
```
### Solution:
Fallback to an empty string if `post.get('media_url')` yields a None value.
OPW-6449357
Forward-Port-Of: odoo/enterprise#127049
Forward-Port-Of: odoo/enterprise#126987Bulk product imports could fail when subscription-related settings were updated because a required helper was missing. This restores the missing logic so subscription products can be imported reliably without blocking business workflows.
Original PR description
The port https://github.com/odoo/enterprise/commit/68640b5bddf51a8cbf58d3af3628cd4b57e08913 added a call to self._get_confirmed_order_lines() in product.template.write() (on import, when recurring_invoice changes), but the helper itself was never ported to 19.0. Importing products in bulk then fails with AttributeError: 'product.template' object has no attribute '_get_confirmed_order_lines'. Restores the method from master (PR https://github.com/odoo/enterprise/pull/117046) at the end of the ProductTemplate class. Forward-Port-Of: odoo/enterprise#122745 Forward-Port-Of: odoo/enterprise#122146
Users who have both Partner Commissions and Purchase access can now create and view purchase orders as expected. This prevents commission-related access rules from unintentionally blocking normal purchasing work while keeping commission-only restrictions in place.
Original PR description
## Current behavior: The user Partner Commissions access rights as All Documents or Own Documents and Purchase access rights as User. With this configuration, the user is unable to create new…
## Current behavior: The user Partner Commissions access rights as All Documents or Own Documents and Purchase access rights as User. With this configuration, the user is unable to create new Purchase Orders, and existing Purchase Orders are also not visible in the Purchase module. ## Expected behavior: The expected behavior is that the user should be able to create and view Purchase Orders with these access rights. Additionally, clarification is required regarding the purpose of the new Partner Commissions access group. ## Steps to reproduce: - Go to user and assign Partner Commission rights as All or own document. - On Purchase, select group as User. ## Cause of the issue: partner_commission adds commission-specific purchase order record rules, but purchase users have no matching purchase-order rule in that module. For mixed-role users, the commission rule ends up restricting standard purchase orders as well. ## Fix: Apply the module's explicit all-purchase rule to purchase users so mixed users keep base procurement access while commission-only users remain restricted by the commission rules. opw-6366074 Forward-Port-Of: odoo/enterprise#126003
Financial reports now show the current month and quarter correctly when opened with a yearly default period. Custom comparison dates are also refreshed immediately and capped at today, preventing future-dated defaults in yearly reports.
Original PR description
When opening reports with `default_opening_date_filter='this_year'`(e.g., P&L, Partner Ledger), the date filter dropdown showed incorrect defaults for non-selected period types: - Month showed the…
When opening reports with `default_opening_date_filter='this_year'`(e.g., P&L, Partner Ledger), the date filter dropdown showed incorrect defaults for non-selected period types: - Month showed the last month of the fiscal year (e.g., December) instead of the current month - Quarter showed Q4 instead of the current quarter This happened because `initDateFilterState()` used the backend's `date_to` (fiscal year end) as the reference for computing all filter periods. For `this_year`, `date_to` is the year-end date (e.g., 2026-12-31), so `computePeriodRange()` for month/quarter returned periods containing that date rather than today's date. Reports with `this_month` or `today` defaults were unaffected because their `date_to` is naturally close to today. Now, non-selected filters use today as their reference date on initial load whenever today falls within the report period, while the selected filter continues to use the backend's `date_to`, preserving the alignment behavior introduced in the date filter refactor (https://github.com/odoo/enterprise/commit/40484f985f511edd7ba2ae759ce63ef564bcf1f7). Additionally, selecting the custom comparison filter now triggers an immediate reload so its default date range is recomputed by the backend. The custom comparison range is initialized using the current fiscal year up to today, capping its end date to today instead of inheriting the report's `date_to`, which could otherwise default to a future date for yearly reports. task-6229588
Shifts for employees with flexible schedules and no set start or end time are now included in both planning views and timesheet analysis. This prevents planned work from being missed in reporting, giving managers a more accurate view of allocated time.
Original PR description
## Behavior Before the PR When an employee did not have explicit `hours_from` and `hours_to` values defined, their shift was in the **Schedule by X** pivot view but was not included in the **Planning…
## Behavior Before the PR When an employee did not have explicit `hours_from` and `hours_to` values defined, their shift was in the **Schedule by X** pivot view but was not included in the **Planning / Timesheets Analysis** report. ## Steps to Reproduce 1. Create an employee with a Flexible Working Schedule in the Employee form, or configure working hours where both `Hour from` and `Hour to` are left unset. 2. Add a shift for this employee linked to a project and a task. 3. Publish the shift. 4. Navigate to **Planning → Schedule → By Project**, switch to the pivot view, and observe that the shift created in step 2 appears and is counted. 5. Navigate to **Planning → Reporting → Planning / Timesheets Analysis**, switch to the pivot view, and observe that the same shift does not appear. ## Behavior After the PR When an employee does not have explicit `hours_from` and `hours_to` values, their shift is now considered valid in both the **Schedule by X** views and the **Planning / Timesheets Analysis** report. ## Additional Notes - In earlier versions of Odoo, the `Work From` and `Work To` fields were mandatory. With a change to flexible working schedules and the option to define only the total number of hours per day, these fields may now be left empty. This change exposed the underlying issue addressed by this fix. task-[5969788](https://www.odoo.com/odoo/project/4105/tasks/5969788)
Users can now be re-invited to a shared Documents folder after their previous access has expired. This prevents misleading success messages and ensures invited portal users regain access as expected.
Original PR description
Sharing a folder with a portal user with an expiration date cannot be done again after the access has expired. The sharing dialog reports success, but the user does not get access and is no longer…
Sharing a folder with a portal user with an expiration date cannot be done again after the access has expired. The sharing dialog reports success, but the user does not get access and is no longer listed. ### Steps to reproduce - In Documents, share a folder with a portal user and set an expiration date. - Wait until the expiration date has passed. - Share the same folder with the same user again from the invite box. => The dialog says the member was added, but the user has no access and does not appear under "People with access". ### Cause The invite box has no expiration field. When re-inviting a user, it updates the existing `documents.access` record and passes `None` for the expiration, which keeps the old `expiration_date`. If that date is already in the past, the user remains expired even though the invite reports success. ### Fix Pass `False` instead of `None` when inviting a member so the existing record's expiration date is cleared. Re-inviting an expired user now restores access. Setting an expiration from the "People with access" list is unchanged. opw-6387559 Forward-Port-Of: odoo/enterprise#127050 Forward-Port-Of: odoo/enterprise#125140