Monday, March 23, 2026
61 changes · saas-19.1
Resolved issues and error corrections
This update corrects a bug in the SendCloud delivery service that was preventing the system from correctly processing delivery requests. The issue stemmed from an incorrect use of Python slicing, which was causing a data retrieval error. The fix ensures reliable delivery processing.
Original PR description
Slicing in Python returns a sub-list, even for a single element. Doing `res[:1]` does not return the first element so doing `.get` causes an error. This was not caught because the tests do not run in CI due to the tags on the class. Forward-Port-Of: odoo/enterprise#111254
This update fixes an issue where the Report Editor wouldn't automatically focus on the editable field after making changes like deleting rows or columns. This ensures a smoother user experience when working with report designs, preventing unnecessary clicks and improving efficiency. The change was made to address a test failure related to browser focus behavior.
Original PR description
PR [1] ensures that editable is focused after deleting row or column from table menu by preventing default while clicking on table menu button. This change causes test [2] to fail if a table menu test runs beforehand, due to browser’s native focus behavior. This commit ensures that editable is focused whenever clicking on t-field. [1]: https://github.com/odoo/odoo/pull/249256 [2]: https://github.com/odoo/enterprise/blob/19.0/web_studio/static/tests/client_action/report_editor/report_editor_dom_edition.test.js#L456-L478 Community PR: https://github.com/odoo/odoo/pull/249256 task-5725593 Forward-Port-Of: odoo/enterprise#109034
This update resolves an error that occurred when activating the 'hr_expense_stripe' module with unsupported currencies (like INR). The module will no longer attempt to create a specific journal, and existing company currencies will now be used as a fallback, ensuring the invoicing dashboard functions correctly.
Original PR description
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to…
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to reproduce: (19.0) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` - Create New company > Set `Country` and `Currency` (eg: India and INR) > Switch to New company > Open `Invoicing` you will get the error. Steps to reproduce: (saas-19.1) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` > Open `Invoicing` you will get the error. Traceback: `ValueError: Expected singleton: res.currency()` In this [PR], the behavior is such that if `company.stripe_currency_id` is not set, we do not create the "Stripe Issuing". In 19.0, `@template` was executed after the post-init hook, and we were preventing the creation of the [journal] at that stage. However, when a new company is created, the template data is automatically loaded for companies with a matching chart of accounts. As a result, the `stripe_issuing_journal` is created, which leads to the error. However, in saas-19.1, due to recent improvements in a [commit], the `@template` will now loads data for companies without post init hook. As a result, the `stripe_issuing_journal` is being created, and we are encountering an error. Solution: - The`Stripe Issuing` journal will no longer be created on installing the module. - For existing databases, we will use the company currency as a fallback value to ensure that a valid currency is applied. [PR]: https://github.com/odoo/enterprise/pull/96271 [journal]: https://github.com/odoo/enterprise/blob/fea009f98885a97439edfea75376b7323c8c9a03/hr_expense_stripe/models/res_company.py#L186-L187 [commit]: https://github.com/odoo/odoo/pull/228950/changes/21fd14ed5e8bdd2cf203d466069437a62a87f2bd sentry-7284934493 Forward-Port-Of: odoo/enterprise#108436
This update fixes an issue where the "Submit" button was hidden when creating return types in the account reports. The change removes an outdated field requirement, ensuring the button is always visible for users to complete the return type creation process. This improves usability for users generating return reports.
Original PR description
When a user creates a return_type, the submit button is not visible as there is no type_external_id. Since now, we have the states_workflow this is not useful anymore. This commit is basically a back port of https://github.com/odoo/enterprise/commit/305b0078e584487036d907d6e18b7911bc7ff1de Forward-Port-Of: odoo/enterprise#110328
This update corrects a previous error that occurred when the 'Payroll: Update Data' cron job ran, specifically within the Saudi Arabian payroll configuration. The issue stemmed from deleting salary rule categories, which caused a data mismatch during the update process. This fix ensures that the rule category data is updated before the salary rule data, preventing the error and maintaining accurate payroll processing.
Original PR description
Currently, an error occurs when the "Payroll: Update Data" scheduled action is executed. **Steps to Reproduce:** - Install `l10n_sa_hr_payroll` with demo data. - Switch to `Saudi Arabian` company. -…
Currently, an error occurs when the "Payroll: Update Data" scheduled action is executed. **Steps to Reproduce:** - Install `l10n_sa_hr_payroll` with demo data. - Switch to `Saudi Arabian` company. - Go to `Payroll` > `Configuration` > `Salary` > `Rule Categories`. - Delete all records related to the Saudi Arabian company. - Go to `Scheduled Actions` and run `"Payroll: Update Data"`. `ValueError: External ID not found in the system: l10n_sa_hr_payroll.l10n_sa_category_provision` After [this commit], the category_id field becomes non-required, allowing users to delete a rule category record even if it is linked to a salary rule. When updating the data file [1], this causes an error due to the missing rule category [2]. This commit ensures that, when updating the salary rule data, the rule category data is updated beforehand, as shown here [3]. [this commit]: https://github.com/odoo/enterprise/commit/c663fd2a81b7f6b34f8199fdbdc4a75c4f21379e [1]- https://github.com/odoo/enterprise/blob/5ab4cb8bbf8211783a23a4334b633d52633b0324/l10n_sa_hr_payroll/models/hr_payslip.py#L157-L165 [2]: https://github.com/odoo/enterprise/blob/5ab4cb8bbf8211783a23a4334b633d52633b0324/l10n_sa_hr_payroll/data/hr_salary_rule_saudi_data.xml#L249 [3]: https://github.com/odoo/enterprise/blob/5ab4cb8bbf8211783a23a4334b633d52633b0324/l10n_ke_hr_payroll/models/hr_payslip.py#L9-L18 sentry-7349905716
This update fixes an error in the reports generated for Ecuador (l10n_ec_reports_ats) by ensuring the correct 'tipoCliente' value is used for foreign partners. Previously, the system incorrectly identified company types, leading to inaccurate tax reporting. This change aligns with AFIP requirements and ensures compliance.
Original PR description
Since `tipoCliente` is now determined using the computed `is_company` field, the test data must reflect this logic. `partner_ext` represents a foreign partner and is considered a company, therefore its `tipoCliente` should be set to '02'. See: https://github.com/odoo/enterprise/commit/a779badac35cf4a8f483f490e8ae29eb6bf3d2c5 `l10n_ar_edi`: For foreign partners, AFIP requires the CUIT pais based on the partner’s country and document type, not on partner.is_company. In multi-localization databases, is_company may be influenced by local heuristics and lead to picking the wrong foreign tax identifier. Use the identification type instead: VAT documents map to the legal-entity CUIT pais, while non-VAT documents map to the natural-person one. See: https://github.com/odoo/enterprise/pull/86089#discussion_r2128977870 runbot-241126
This update resolves a technical issue related to how geographic data (specifically topoJSON) is processed within the Odoo Enterprise spreadsheet reports. The fix ensures accurate display of maps and charts based on location data, improving the reliability of reports. This change primarily impacts users who rely on location-based data visualizations.
Original PR description
test adaptation Counterpart of github.com/odoo/odoo/pull/248847 Task-5224009 Forward-Port-Of: odoo/enterprise#107912
This update fixes a bug preventing portal users from viewing timesheets on helpdesk tickets linked to projects with 'Invited internal and portal users' visibility. The change expanded the domain to include both 'portal' and 'invited_users' visibility options, ensuring correct timesheet display for all users.
Original PR description
Steps to reproduce: - Create Project A with visibility set to `Invited internal and portal users.` - Create a Helpdesk Team and assign Project A to it. - Create a helpdesk ticket. - Log a timesheet…
Steps to reproduce:
- Create Project A with visibility set to `Invited internal and portal users.`
- Create a Helpdesk Team and assign Project A to it.
- Create a helpdesk ticket.
- Log a timesheet on the ticket and share the ticket with the portal user.
- Log in as the portal user and check the timesheet.
- Observe that the timesheet is not visible to the portal user.
Cause:
- After introducing the `invited_users` option in `privacy_visibility`, the portal domain in `_timesheet_in_helpdesk_get_portal_domain` was not updated.
- The domain was still defined as: `('project_id.privacy_visibility', '=', 'portal')`
- As a result, timesheets linked to projects with visibility set to “Invited internal and portal users” were excluded from the portal user’s view.
Solution
Update the domain to include both visibility options: `('project_id.privacy_visibility', 'in', ['portal', 'invited_users'])`
- This ensures timesheets are visible to portal users when the project visibility is either portal or invited_users.
task-5924243
Forward-Port-Of: odoo/enterprise#107800This update resolves an issue where the topbar menu wasn't correctly updated after a user opened a menu using an AI Agent. The fix ensures the topbar accurately reflects the currently active menu, improving the user experience when interacting with AI-powered features. This enhances usability and consistency.
Original PR description
Purpose: -------- When a menu (view) was opened through an AI Agent, the menu in the topbar was not updated. This commit fixes this behaviour by setting the menu when the menu's action has been loaded Task-6017607 Forward-Port-Of: odoo/enterprise#109929
This update automatically calculates and transmits the required perception commission for Swiss employees through the Swissdec system. This ensures accurate and timely reporting for tax compliance, addressing a previous issue with manual calculations. The change impacts the l10n_ch_hr_payroll module.
Original PR description
task-6050810 Forward-Port-Of: odoo/enterprise#111143
This update resolves a problem where the website's tour process was failing due to timing issues, particularly with translation loading in recent Chrome versions. The fix adds a temporary step to ensure translations load before the tour continues, preventing interruptions and ensuring a smoother user experience.
Original PR description
This commit adds an intermediary step ensuring the proper page has been reached before actually doing the checks and avoiding to let startup requests (like the loading of the translations) pending at the end of the tour (and the eventual stop of the runner browser). Note: this is most likely due to a timing (indeterministic by nature) change, emphasised by recent Chrome versions (like v145). runbot-239128 Forward-Port-Of: odoo/enterprise#111013 Forward-Port-Of: odoo/enterprise#110648
This update resolves a test issue where simultaneous data synchronization in the Point of Sale (POS) tax module caused errors. The fix ensures that backend calls complete before the test continues, improving test reliability and preventing disruptions. This enhances the overall stability of the POS tax functionality.
Original PR description
In the test test_pos_avatax_flow, two calls are made to get_order_tax_details almost simultaneously, which causes the second call to raise an error due to both call trying to sync the same order at the same time. This commit fixes the test by waiting for the backend calls to be done before proceeding with the test next steps. runbot-error: 238871, 238872 Forward-Port-Of: odoo/enterprise#110341
This update corrects a bug where changes to view ordering within the Odoo Studio were not being applied correctly. The fix involved updating the default order setting to be applied through the designated `defaultOrderBy` attribute on the related model, ensuring consistent view ordering for users.
Original PR description
Bug === When changing the order of the views using studio, it wasn't applied. The reason is that we add a default order at the wrong place in JS, it should be done with the attribute made for that, `defaultOrderBy` on the relational model. Task-6047024 Forward-Port-Of: odoo/enterprise#111395 Forward-Port-Of: odoo/enterprise#111091
This update resolves an issue with automatic GST token refreshes in the Odoo Enterprise system. The automatic refresh process has been disabled, and now the refresh is triggered manually when needed, ensuring compliance and reducing potential operational overhead. This change improves stability and control over token management.
Original PR description
With this PR, the GST token refresh cron interval is updated from 5 hours to 9999 months to effectively disable automatic execution. The cron will instead be triggered manually from `validate_otp` and `_cron_refresh_gst_token` based on the token expiration time. Forward-Port-Of: odoo/enterprise#109937
This update clarifies error messages related to Instagram integration (code 9004) within the Odoo Enterprise platform. The change provides users with more helpful guidance when encountering these issues, reducing the need to contact support. This improves the overall user experience and stability of the Instagram feature.
Original PR description
Purpose ======= Explain the possible errors for the code 9004, to help users debugging their Odoo servers without creating a ticket. Task-5972197 Forward-Port-Of: odoo/enterprise#110571 Forward-Port-Of: odoo/enterprise#109319
This update corrects a visual issue in the accounting reports where the company header was grayed out in dark mode. The change ensures consistent branding and a better user experience by using a standard muted data color, aligning with the overall design of the application.
Original PR description
Before this pr: - The company header in the accounting reports is grayed out in the light mode only, not in the dark mode. Reason: - Until now, we have been using the hard-coded 'lightgrey' color for the company header. After this pr: - In this pr, we are changing the color of the company header from hard-coded 'lightgrey' color to the standard variable color '--AccountReport-muted-data-color' used for muted data in account reports. Task-5960592 Forward-Port-Of: odoo/enterprise#111509 Forward-Port-Of: odoo/enterprise#110108
This update resolves an issue where long tax amounts in Ke revenue reports were causing display problems. The fix ensures that tax totals are correctly rendered, regardless of the numerical size, improving the clarity and accuracy of financial reports. This enhancement impacts the user experience for Ke revenue reporting.
Original PR description
This commit aims to: Fix Display issue when the amount is long. task-5162891 Forward-Port-Of: odoo/enterprise#111003 Forward-Port-Of: odoo/enterprise#100319
This update fixes an issue where the Gemini AI feature sometimes returned empty responses to users, creating a confusing 'broken' experience. The fix automatically retries the request with a slightly increased processing budget and, after three attempts, gracefully informs the user of the failure. This ensures a more reliable and consistent AI experience.
Original PR description
It often occurs that gemini responses come back empty without anything to show to the users. Specifically, the response object has content but the "parts" are empty - the place were you either get a function call or a message to the user by the LLM. Prior to this commit, when this occured, we didn't perform any explicit handling. We would always just return what the LLM responded with, which when empty would be nothing. UX wise, it would seem like something broke because the user would basically get no reply. In this commit, we add a retry mechanism in `_request_llm_google` of `llm_api_service.py`, where if we get no response, we increase the thinking budget of the next request to 512 and try again. 512 tokens were chosen completely arbitrarily - anecdotally, the model should use around 300 thinking tokens for its tasks so 512 should be enough. After 3 unsuccessful tries, we send a failure response to the user. Task-5959805 Forward-Port-Of: odoo/enterprise#108755
This update fixes a bug where project timesheets didn't accurately reflect changes in manufacturing employees. The fix automatically updates the AAL (analytic accounting line) associated with the work center when an employee is switched, ensuring accurate tracking of labor costs on the project dashboard. This improves the reliability of project cost reporting.
Original PR description
### Steps to reproduce: - Create an MTO product and another Service product that create a project and task - Create a quotation with both products - Create two employees with different hourly cost - Go to Manufacturing order - Configure an employee to manufacture the product at a work station. - Observe the project dashboard - Go back to the MO and change the employee on the work station - Notice the project dashboard Timesheets section doesn't have any change on the amount ### Cause: This is happening because when changing the employee we don't modify anything in the AAL linked to the work station. As we only modify the AAL when the duration change. ### Fix: We call _create_analytic_entry when we change the employee on the work station to change the amount and the employee_id for the AAL. opw-5939321 Forward-Port-Of: odoo/enterprise#111040 Forward-Port-Of: odoo/enterprise#109695
This update resolves an issue preventing invoices with the ICBPER tax code from generating correctly. The fix addresses a technical problem related to how the system handles fixed taxes, ensuring invoices with this tax type now process without errors. This improves the accuracy of invoice generation for Peruvian businesses.
Original PR description
**Steps to reproduce:** 1. Install module `l10n_pe_edi`. 2. Switch company to PE. 3. Create a tax: - Name: ICBPER - Amount type: Fixed - Code: ICBPER - Amount: 0.5(e.g.) - Set the tax group to ICBPER…
**Steps to reproduce:**
1. Install module `l10n_pe_edi`.
2. Switch company to PE.
3. Create a tax:
- Name: ICBPER
- Amount type: Fixed
- Code: ICBPER
- Amount: 0.5(e.g.)
- Set the tax group to ICBPER (In Advance Option)
4. Create a invoice and add a product with ICBPER tax.
5. Post the invoice and click "Process Now" (at header).
**Issue:**
Processing the invoice raises:
AttributeError: 'dict' object has no attribute '_get_downpayment_lines'
**Cause:**
When `fixed_taxes_as_allowance_charges` is True, `_setup_base_lines()` calls `_turn_emptying_taxes_as_new_base_lines()`, which splits fixed taxes (e.g., ICBPER) into separate base lines.
During this process, `base_line['record']` is no longer the original `account.move.line` record. Instead, it becomes a dictionary containing record under `base_line['record']['record']`.
- With the flag enabled: `base_line['record']` -> dict `line._get_downpayment_lines()` -> AttributeError
- With the flag disabled: `base_line['record']` -> `account.move.line``line._get_downpayment_lines()` -> works correctly
The Peru EDI implementation directly accesses `base_line['record']` expecting an `account.move.line`. The the nested dict structure causes the crash during file generation.
**Solution:**
Override `_add_invoice_config_vals()` to explicitly set `fixed_taxes_as_allowance_charges = False`
- Add test to ensure invoices with ICBPER fixed taxes generate XML without error
**opw-5809939**
Forward-Port-Of: odoo/enterprise#108638This update resolves issues related to how client IDs are formatted within the Odoo Enterprise payroll module (l10n_be_hr_payroll). Specifically, it adapts to a new naming convention for Client IDs, ensuring compatibility and preventing potential errors. The changes also include several bug fixes related to connection and configuration processes within the payroll module.
Original PR description
Forward-Port-Of: odoo/enterprise#111276
This update resolves an issue where CFDI reports incorrectly displayed '99 - False' instead of '99 - Por definir' for payment method 99. The fix ensures that the report accurately reflects the payment method selected during invoice creation, improving report accuracy for Mexican tax compliance.
Original PR description
**PROBLEM** PR https://github.com/odoo/enterprise/commit/843d57b25f925a5d4f1848b85717adb4d1a9d388 Archives payment method 99, but because it's archived `_l10n_mx_edi_get_extra_invoice_report_values()` doesn't retrieve it. This leads the pdf report to display '99 - False' instead of '99 - Por definir'. **STEP TO REPRODUCE** 1. Create an invoice with the mx company. 2. Set the due date sometime in the month later. (To have the PPD payment policy on the invoice). 3. Send and generate the invoice using cfdi. opw-5927655 Forward-Port-Of: odoo/enterprise#111051 Forward-Port-Of: odoo/enterprise#107267
This update resolves issues with overtime calculations related to employee timezones. Previously, the system incorrectly handled overlapping attendances and failed to properly delete outdated overtime lines, leading to inaccurate reporting. This fix ensures accurate overtime tracking regardless of employee timezone settings.
Original PR description
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a…
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a period, then create two consecutive midnight-to-midnight attendances in the employee's local timezone. Creating the second attendance crashes with: "ValueError: Expected singleton: hr.attendance.overtime.line(...)". Steps to reproduce (stale overtime lines): With the same setup, delete the attendance after it generated overtime lines. The overtime lines remain in the database instead of being removed. The singleton crash occurred because `end_of_day` in `_get_overtime_intervals` was computed as a naive datetime, implicitly treated as UTC. For UTC+ timezones, the actual local end of day is earlier than UTC midnight. As a result, overtime intervals were computed with a stop time extending past the real local midnight into UTC time. When consecutive attendances were processed together, these extended intervals overlapped. The `Intervals` class (`keep_distinct=True`) merges overlapping intervals into a single entry with a multi-record recordset as payload. The subsequent `overtime.rule_ids.work_entry_type_id` and `overtime.status` calls expected a singleton but received a multi-record set, causing the crash. The same multi-record issue also affected the iteration in `_set_real_overtime_intervals` and the overtime work entry loop in `_get_attendance_intervals`. The stale overtime lines issue occurred because `_get_overtimes_to_update_domain` (hr_attendance) built its search date range from raw UTC `.date()` values instead of the employee's local timezone. For UTC+ employees whose attendance spans local midnight, the overtime line is dated in the next local calendar day. Since the domain was derived from UTC dates, that next local day fell outside the search range, so the overtime line was never found and deleted when the attendance was removed. Solution: - In `_get_overtime_intervals`, localize `end_of_day` to the employee's timezone before converting to UTC, so overtime intervals are correctly bounded by the local end of day. - In `_set_real_overtime_intervals` and the overtime loop in `_get_attendance_intervals`, iterate over individual records from potentially multi-record `Intervals` payloads to avoid singleton errors. - In `_get_overtimes_to_update_domain` (hr_attendance), localize check_in/check_out to the employee's timezone before computing the date range so overtime lines for dates that only exist in local time are correctly included in the delete-and-recreate cycle. opw-5931665 Forward-Port-Of: odoo/enterprise#109419
This update corrects a problem where appraisal dates weren't being calculated correctly due to a timing issue in the testing process. The fix ensures that appraisal settings are properly applied before test employees are created, resulting in accurate appraisal date calculations for employees.
Original PR description
Issue: The computation of the next appraisal date for employees depends on setting the appraisal plan for a company or changing the company's settings for `duration_after_recruitment`, `duration_first_appraisal`, `duration_next_appraisal`. Fix: Moving the test employee creation after configuration of the company settings for the appraisal plan. task-6050719 Forward-Port-Of: odoo/enterprise#111345 Forward-Port-Of: odoo/enterprise#111265
This update fixes a visual issue where blank spaces appeared in activity cards after a description was cleared. The change ensures that the activity card only displays content when there's actual information, preventing unnecessary empty space and maintaining a cleaner user interface. This improves the overall user experience.
Original PR description
**Description of the issue/feature this PR addresses:** When an activity description is cleared, the stored value may still contain empty HTML content. The UI was still rendering this as a note,…
**Description of the issue/feature this PR addresses:** When an activity description is cleared, the stored value may still contain empty HTML content. The UI was still rendering this as a note, resulting in unnecessary blank space in the activity card. **Current behavior before PR:** Even when the activity description is cleared and contains only empty HTML, the activity note container is still rendered, leaving visible empty space in the UI. **Desired behavior after PR is merged:** The activity note is rendered only when it contains meaningful content. Empty HTML descriptions are ignored, preventing blank space from appearing in the activity card UI. Before <img width="445" height="84" alt="image" src="https://github.com/user-attachments/assets/f6648bb0-78d9-4063-a347-fe664370106e" /> After <img width="459" height="72" alt="image" src="https://github.com/user-attachments/assets/84c2063a-7c68-4dfe-b729-566ca4b5dcd1" /> task-[4752613](https://www.odoo.com/odoo/project/1519/tasks/4752613) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254708 Forward-Port-Of: odoo/odoo#252139