Daily updates from Odoo
Navigate
Branch
Thursday, April 23, 2026
300 changes
27 changes
Enhancements to existing features
Users can now split a manufacturing order directly from the serial number generation wizard. This makes it possible to assign one serial number per sub-order in a single step, instead of having to choose between splitting the order and generating serials separately.
Original PR description
Since 4bb4e08066449, producing multiple serial that have been generated is only doable on one mo. We can split mo. we can generate serial number but we cannot do both at the same time. This commit adds a new button into the generate serial wizard to split the main mo into the number of serial wanted and attribute one for each sub mo. 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#259156 Forward-Port-Of: odoo/odoo#255577
Resolved issues and error corrections
This update corrects a reporting setting that was left in an outdated format in several local tax reports. As a result, migrated reports for Spain, Italy, Luxembourg, and Uganda can open normally again without validation errors.
Original PR description
- This aggregation expression used to have 'cross_report' as subformula. Though, it was useless (since the aggregation only uses term from the same report), and the subformula was removed from the…
- This aggregation expression used to have 'cross_report' as subformula. Though, it was useless (since the aggregation only uses term from the same report), and the subformula was removed from the data file without explicitly resetting it to False. This became a problem in 18.3, because the cross_report syntax changes. Because of that, a migrated report failed to open, since it still was using the old syntax on that expression. We fix that by explicitly emptying the subformula. see https://github.com/odoo/odoo/pull/193106 ```python3 Opération invalide Dans le rapport "Section I (LU)", à la ligne "472 - Autres Ventes / Recettes", avec le libellé "balance", Le format de l'expression de rapport croisé est invalide. Format attendu : cross_report(<report_id>|<xml_id>) Exemple : cross_report(my_module.my_report) ou cross_report(123) ``` opw-6103170 upg-4166654(lu) upg-4163103(it) upg-4175631(ug) upg-4177165(es) 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#258826
A bug that could cause an error while editing salary adjustments has been fixed. The system now handles missing start dates safely, preventing a traceback during form updates and making the payroll workflow more reliable.
Original PR description
This task guard against falsy date_start in _compute_estimated_end to avoid adding a relativedelta to False, fixing a traceback appearing during onchange. task-6139538 Forward-Port-Of: odoo/enterprise#114332
This fix prevents an error when users click certain cells in the Trial Balance report, specifically for Undistributed Profits/Losses. It restores the expected report details so users can open the related information without interruption.
Original PR description
This error occurs when clicking on any cell for `Undistributed Profits/Losses` in the `Trial Balance` report. Steps to reproduce: - Install `Accounting` module - Create `Journal Entry` with past-year…
This error occurs when clicking on any cell for `Undistributed Profits/Losses` in the `Trial Balance` report. Steps to reproduce: - Install `Accounting` module - Create `Journal Entry` with past-year `Accounting Date` (eg: 31-12-2025) and include one `Journal Items` for `Undistributed Profits/Losses` - Open `Trail Balance` report and click on any cell for `Undistributed Profits/Losses` Traceback: `KeyError: 'report_line_id'` Before this [commit], we were returning fields with `null/None` values. After the commit, fields containing `null/None` [value] are removed, and only fields with valid values are returned. As a result, when the `dispatch_report_action` function is called, the `report_line_id` is missing in `params`. [commit]: https://github.com/odoo/enterprise/pull/102808/changes/b92dc397bef029472a40223f51b611cdf5b631dc [value]: https://github.com/odoo/enterprise/blob/626b8157bcea2e3843cd9d5d0c0036e302b8e5ce/account_reports/utils/report_data_objects.py#L42-L43 sentry-7372351871 opw-6119913 Forward-Port-Of: odoo/enterprise#113421
This change stops combo products from being selected directly in the mobile sales order line form. It prevents orders from ending up with an empty, zero-priced line and missing the required child items, improving order accuracy and reducing follow-up corrections.
Original PR description
Combo products bypasses the configurator in mobile view, resulting in a 0-price line with no child lines. Exclude them via domain on the field. opw-5999935 Forward-Port-Of: odoo/odoo#260056 Forward-Port-Of: odoo/odoo#256790
Downloading a receipt for kiosk self-orders now works correctly. This fixes an error that could stop users from viewing or saving the receipt for these orders.
Original PR description
Currently an error occurs when the user tries to `Download Receipt` of self-orders as the following steps: - Install the pos_self_order module - Create a new POS shop with `Self Ordering` as `Kiosk` - Add Online `Payment Methods` on the above POS shop - Make an order from kiosk mode - Go to Point of Sale > Orders > Orders - Open the recent order which was created from the kiosk. - Click `Download Receipt` > Error Error: `QWebError:Error while rendering the template: AttributeError: 'bool' obje...` This issue occurs because, while rendering pos_order_receipt_header`, the `preset` value is `False`. Attempting to call `.get()` on a falsy value leads to an error. This commit fixes the issue by accessing `preset` only when it is available, preventing errors during rendering. sentry-7402711985 Forward-Port-Of: odoo/odoo#259336
A rendering issue could turn a normal percent sign in website and template text into a doubled percent sign, such as displaying "400%%" instead of "400%". This fix ensures text is shown exactly as intended when no placeholder values are present.
Original PR description
`_compile_format` unconditionally escaped `%` to `%%` to protect against Python's `%`-formatting, but only appended the `% (values,)` formatting operation when `#{...}` placeholders were present. With no placeholders, the escape was never undone and `%%` leaked into the rendered output.
This went unnoticed until the introduction of paramteric t-call: https://github.com/odoo/odoo/commit/eb6e88a25050
And since we use `.translate` and `.f` directly in existing views this became apparent
Example:
```xml
<t t-call="website.s_wd_testimonial"
_testimonial_quote.translate="...by 400%."/>
```
will be rendered as `...by 400%%.` on the page.
To prevent this, we can simply check for the absence of values and simply return the repr as is if there isn't any.
Forward-Port-Of: odoo/odoo#260434This update prevents an error that could occur when opening account report information. It ensures the report uses the correct update method for its internal data, so reports load reliably again.
Original PR description
Currently, an error occurs when retrieving account report information. ``` File "/home/odoo/odoo18/enterprise/account_reports/models/account_report.py", line 1475, in _create_hierarchy…
Currently, an error occurs when retrieving account report information.
```
File "/home/odoo/odoo18/enterprise/account_reports/models/account_report.py", line 1475, in _create_hierarchy
render_lines(root_account_groups, current_level, root_line_id, skip_no_group=False)
File "/home/odoo/odoo18/enterprise/account_reports/models/account_report.py", line 1373, in render_lines
child_line.update
^^^^^^^^^^^^^^^^^
AttributeError: 'AccountReportLineData' object has no attribute 'update'
```
After the [recent commit], all lines, columns, format_params, and annotations are converted into custom objects (AccountReportLineData). However, the code still attempts to use the update() method on these objects, which raises an error [1] since AccountReportLineData does not have an update method.
This commit ensures that the update_value() method is used to update AccountReportLineData objects, as intended, like here [2].
[recent commit]: https://github.com/odoo/enterprise/commit/6608d5c21a7fb9d57786c2a7618b878e244bd420
[1]- https://github.com/odoo/enterprise/blob/cde4e05de82476655764f8c9fe8734416d4a35bf/account_reports/models/account_report.py#L1373-L1377
[2]- https://github.com/odoo/enterprise/blob/cde4e05de82476655764f8c9fe8734416d4a35bf/account_reports/models/account_report.py#L6565
sentry-7403925422
Forward-Port-Of: odoo/enterprise#113668This update removes the "17" tax tag from several French service tax rates where it did not belong. It helps ensure French tax reporting stays accurate by applying that tag only to goods, not services.
Original PR description
**Issue:** In French localization, a tax tag (i.e. "17") was wrongly added on several taxes for service by a fix: https://github.com/odoo/odoo/commit/f9237cfbb6a9ffbd0a392e4e77e097d5963a5fc3 This tax tag should only be applied on taxes for goods, not service. **Solution:** Remove the tax tag from the following taxes: - 20% EU S - 8.5% EU S - 10% EU S - 5.5% EU S - 2.1% EU S opw-5871998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260617
Imported XML files are now kept attached to the related record instead of being detached during import. This prevents access errors in certain invoice workflows, including Mexican electronic invoicing, when users open bills later.
Original PR description
When importing files (manually or from email alias), we unattach the xml files, it can lead to access error in some flows like with l10n_mx_edi Steps to reproduce the flow that triggered the bug: - Install l10n_mx_edi and select MX company - Create an email alias for purchase journal - Receive email with xml file - Create a user with 'group_user' role, 'Administrator' accounting access rights - Login with this user and open the created bill -> Access Error This is because we unattach xml attachmentss when importing them, by setting `res_id` to 0 and `res_model` to False. The mx edi flow adds the `l10n_mx_edi_cfdi_attachment_id` via `_get_mail_thread_data_attachments` which lead to an access error during the `fetch` method opw-5953578 closes odoo/odoo#260545 X-original-commit: 7023bb316ca266a18abccc7e8c13069deafc562b Signed-off-by: Laurent Smet (las) <las@odoo.com> Signed-off-by: Guillaume Vanleynseele (guva) <guva@odoo.com>
The website builder now applies the correct zoom level to snippets that use scroll-based background effects in the block chooser. This fixes cases where the zoom looked too weak when browsing custom snippets, so the preview matches what users expect.
Original PR description
Commit 468ddd4d244d0098e5c8b9726bc1c85c036a913d changed the viewport height of the iframe in the snippets preview dialog (from `333%` to `100%`). That height is used in the computation of the zoom effect of backgrounds. This computation was not adapted to the change of height, and thus the zoom was too weak. This commit adapts the computation for the zoom to compensate the viewport height change of that previous commit. Steps to reproduce: - Open website builder - Create a bunch of custom snippets (for scrolling in the dialog) - Create a custom snippet which has a background with "Scroll Effect" set to "Zoom In" (or "Zoom Out") - Create a bunch of custom snippets (for scrolling in the dialog) - Open the dialog to "Insert a block", choose the "Custom" category - Scroll - Bug: the custom snippets with zooming task-6088029
Configurable benefits will now appear even when there is no salary summary for the same structure type. This prevents an error when adding these benefits and keeps the employee benefit setup working smoothly.
Original PR description
Cause: After this task https://www.odoo.com/odoo/project/1251/tasks/5419466, the showing of benefits was restricted by mistake to only when there was a salary summary for the same structure type. This meant that adding a configurable benefit would result in a traceback, since the template was then used to get more info later on. Fix: Always show configurable benefits, even if there is no salary summary for the same structure type. task-6126621
Project chatter will no longer automatically record status updates from linked Sales Orders. This reduces unnecessary notifications and keeps project activity history focused on information that is directly relevant to the project.
Original PR description
Before this commit: - The chatter on the Project record tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `project.project`, `project.task` models. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/odoo#258549
Helpdesk tickets will no longer automatically log chatter messages when the linked Sales Order changes status. This reduces unnecessary noise in ticket discussions and keeps the conversation focused on the helpdesk issue itself.
Original PR description
Before this commit: - The chatter on Helpdesk Tickets tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `helpdesk.ticket`. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/enterprise#114078
This update fixes the appearance of contract-related buttons on the employee form. It keeps the “New Contract” label on one line at narrow widths and makes the contract template button match the surrounding interface more consistently.
Original PR description
- Add `text-nowrap` to the "New Contract" button to prevent text from splitting at narrow viewport widths - Fix contract template button styling: remove incorrect classes and align font-size and border with the surrounding UI task-6068488 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#256017
The button for contract templates on the employee form now matches the surrounding interface more closely. This improves the visual consistency of the page and makes the form look more polished for users.
Original PR description
Fix contract template button styling: remove incorrect classes and align font-size and border with the surrounding UI task-6068488 Forward-Port-Of: odoo/enterprise#112113
This update improves how the editor handles text that is written inside inline code. It prevents formatting tools from appearing when they are not useful, and makes sure pasted content is turned into plain text so code stays clean and consistent.
Original PR description
### Purpose of this commit: - Prevent the powerbox and toolbar from opening when the selection is fully inside inline code. When the selection spans inline code and regular text, keep the toolbar visible but ensure formatting commands are applied only to the non-inline-code content. - Ensure that pasted external and editor HTML is converted to plain text when inserted inside inline code. task-5502939 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258781 Forward-Port-Of: odoo/odoo#250911
The calendar popover no longer shows a tooltip when hovering over a boolean field. This avoids displaying unhelpful HTML content and makes the calendar view cleaner and less confusing for users.
Original PR description
Before this commit, the tooltip of a boolean field in calendar popover shows html content when the user hovers the boolean field. This commit removes the tooltip of boolean field in calendar popover since the information inside that tooltip is not really useful for the user. Issue found during the development of task-5994205 Forward-Port-Of: odoo/odoo#260012 Forward-Port-Of: odoo/odoo#259011
Subscriptions that were closed manually by a salesperson will no longer reopen automatically when a payment is approved or an invoice is paid. This prevents unexpected reactivation and avoids follow-up issues for teams managing subscription cancellations.
Original PR description
Before this commit, when a subscription was closed manually by the salesperson, it could be reopened when a transaction was approved or an invoice paid. It could cause issue. In this case, we should not reopen automatically. task-5900481 Forward-Port-Of: odoo/enterprise#113026 Forward-Port-Of: odoo/enterprise#106487
This update resolves a critical issue preventing successful capture or voiding of Adyen payments. The fix ensures the necessary payment provider reference is included in transactions, allowing the payment gateway to process requests correctly. This improves payment processing reliability for Adyen users.
Original PR description
Issue 1: --- Capturing/voiding transaction is failing with the error: `The payment provider rejected the request. Original pspReference required for this operation` Steps to reproduce: 1- Setup Adyen…
Issue 1: --- Capturing/voiding transaction is failing with the error: `The payment provider rejected the request. Original pspReference required for this operation` Steps to reproduce: 1- Setup Adyen payment provider. 2- Enable `Capture amount manually`. 3- Create a SO and confirm. 4- Generate a payment link and pay. 5- In SO, capture the full amount. Cause: --- After https://github.com/odoo/odoo/commit/efc2788dfccd13ee6feb309430ff57e49664ff97, in the payment `_void()`/`_capture()`, a child tx is created. However the child tx is missing the `provider_reference` required to send the payment provider. Issue 2: --- The child tx created for capture/void is always remains in draft state. Cause: --- This is reproduced after https://github.com/odoo/odoo/commit/efc2788dfccd13ee6feb309430ff57e49664ff97 which we create a child tx in capture/void. But in `_search_by_reference` which is called by webhook to find the tx, we are returning the source tx. As a result only the state of the source tx is changed. opw-6120846 opw-6120071 Forward-Port-Of: odoo/odoo#259223
This update ensures that changes to salary information within the salary configurator correctly update related mobility budget calculations. Previously, changes outside this specific context could cause inconsistencies. This change improves the accuracy of mobility budget calculations by limiting updates to the relevant salary data.
Original PR description
For consistency purposes, we only trigger the inverse on the mobility budget computation if we are in the context of the salary configurator. Changing the wage in the back end or changing the employer cost should only touch the wage and not other benefits Forward-Port-Of: odoo/enterprise#112510 Forward-Port-Of: odoo/enterprise#111828
This update resolves an issue preventing developers from creating new Odoo development repositories. Previously, the system required an existing addons directory, now it accepts empty repositories, streamlining the process for building new Odoo modules. This change improves developer workflow and reduces friction for creating new development environments.
Original PR description
Initialize a new empty git repository where you are going to vide-code some new Odoo modules. Because the repository is empty (no addon yet) the CLI fails with an "option --addons-path: the path <path> is not a valid addons directory". This makes vide-coder sad, and bigrams want vide-coders to be happy, so drop the sanity-check and also accept empty addons. Forward-Port-Of: odoo/odoo#259007 Forward-Port-Of: odoo/odoo#256913
This update fixes an issue where scanning GS1 barcodes with leading zeros (like EAN-13 codes) would sometimes fail to correctly identify products. The change ensures that barcodes are accurately matched to their product variants, improving the reliability of the point-of-sale system. This prevents lost sales and ensures accurate product identification.
Original PR description
When scanning a GS1 barcode whose GTIN-14 has a leading zero (e.g. a product stored with EAN-13 "5400000002649" is encoded as GTIN-14 "05400000002649"), the product lookup in _getProductByBarcode failed because the exact string did not match the stored barcode. opw-6117948 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259199
This update fixes an issue where prices in multi-currency Point of Sale (PoS) transactions were incorrectly calculated. Now, prices are accurately converted from the product's native currency to the PoS configuration currency, ensuring accurate pricing across different currencies. This improves the reliability of PoS transactions in international settings.
Original PR description
Before this commit, in a multi-currency environment, the company currency was used to convert the prices, while it was a wrong assumption that the product prices were in the company currency. The products have a currency_id field, and the price should be converted from that currency to the PoS config currency. opw-6065969 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259407 Forward-Port-Of: odoo/odoo#257324
This update resolves an issue where the Point of Sale app on iOS/Safari would unexpectedly crash due to a lost connection to its database. The fix prevents crashes when the app goes to the background or when the operating system temporarily closes the database connection. This ensures a more reliable and stable Point of Sale experience for our iOS users.
Original PR description
On iOS/Safari, the WebKit IDB server process can be killed by the OS (e.g. due to memory pressure when the app is backgrounded), resulting in an UnknownError: "Connection to Indexed Database server lost". Additionally, returning from background can leave the connection in an InvalidStateError "closing" state while this.db remains non-null. opw-5121896 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259697 Forward-Port-Of: odoo/odoo#253943
This update fixes an issue where dropdown menus in the Odoo interface appeared cramped due to missing vertical spacing. The change restores natural spacing, ensuring items don't overlap when group headers are sticky, improving the overall user experience.
Original PR description
Recent structural changes added `p-0` to the menu class, removing the vertical padding from the dropdown. Rather than padding the scroll container directly (which would conflict with sticky group headers), apply `margin-top/bottom` on the first/last children of `.o_select_menu-choices` so the spacing scrolls naturally without creating a gap items could bleed through when a group header is stuck. task-6095912 Forward-Port-Of: odoo/odoo#258929
This update fixes an issue where the system wasn't correctly applying pension fund tax (TC08) during XML import when the tax rate was 0.00. The fix ensures accurate tax assignment, preventing missing tax associations and maintaining compliance with accounting rules. This improves the reliability of imported vendor bills.
Original PR description
### Issue before this commit: When importing vendor bills from XML files containing a pension fund (e.g., type TC08), the pension fund tax was not correctly applied to the invoice lines. As a result,…
### Issue before this commit: When importing vendor bills from XML files containing a pension fund (e.g., type TC08), the pension fund tax was not correctly applied to the invoice lines. As a result, the imported bills were missing the expected tax association. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Set the pension fund type as TC08 (or another one is also fine) in the Advanced Tab of 4% F.Pens. tax 3. Try to upload an XML for vendor bills with a TC08 tax 4. The tax is not associated ### Cause of the issue: The issue was caused by the handling of the VAT rate (AliquotaIVA) when its value was 0.00. The code incorrectly treated this value as falsy, preventing the correct identification and assignment of the pension fund tax during the import process. ### Reason to introduce the fix: The fix ensures that a VAT rate of 0.00 is correctly interpreted as a valid value rather than being ignored. This allows the system to properly detect and apply the pension fund tax during XML import, ensuring accurate tax assignment and compliance with expected accounting behavior. opw-6093352 Forward-Port-Of: odoo/odoo#258341
19 changes
Resolved issues and error corrections
This update corrects a leftover report setting in several localized tax reports so they can open properly after migration. It prevents an invalid cross-report reference from breaking the report for users in Spain, Italy, Luxembourg, and Uganda.
Original PR description
- This aggregation expression used to have 'cross_report' as subformula. Though, it was useless (since the aggregation only uses term from the same report), and the subformula was removed from the…
- This aggregation expression used to have 'cross_report' as subformula. Though, it was useless (since the aggregation only uses term from the same report), and the subformula was removed from the data file without explicitly resetting it to False. This became a problem in 18.3, because the cross_report syntax changes. Because of that, a migrated report failed to open, since it still was using the old syntax on that expression. We fix that by explicitly emptying the subformula. see https://github.com/odoo/odoo/pull/193106 ```python3 Opération invalide Dans le rapport "Section I (LU)", à la ligne "472 - Autres Ventes / Recettes", avec le libellé "balance", Le format de l'expression de rapport croisé est invalide. Format attendu : cross_report(<report_id>|<xml_id>) Exemple : cross_report(my_module.my_report) ou cross_report(123) ``` opw-6103170 upg-4166654(lu) upg-4163103(it) upg-4175631(ug) upg-4177165(es) 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#258826
This update prevents an error that could appear when changing salary adjustment details in payroll. It ensures the form handles missing start dates safely, so users no longer hit a traceback during on-change updates.
Original PR description
This task guard against falsy date_start in _compute_estimated_end to avoid adding a relativedelta to False, fixing a traceback appearing during onchange. task-6139538 Forward-Port-Of: odoo/enterprise#114332
This change stops combo products from being selected directly in the mobile sales order line form. It prevents incomplete lines with a zero price and missing related items, helping ensure orders are created correctly.
Original PR description
Combo products bypasses the configurator in mobile view, resulting in a 0-price line with no child lines. Exclude them via domain on the field. opw-5999935 Forward-Port-Of: odoo/odoo#260056 Forward-Port-Of: odoo/odoo#256790
Project chatter will no longer automatically post tracking messages when a linked Sales Order changes status. This reduces unnecessary notifications and keeps project activity logs cleaner and easier to follow.
Original PR description
Before this commit: - The chatter on the Project record tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `project.project`, `project.task` models. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/odoo#258549
Helpdesk tickets will no longer automatically log chatter messages when a linked Sales Order changes status. This reduces unnecessary noise in ticket discussions and makes the conversation history easier to follow.
Original PR description
Before this commit: - The chatter on Helpdesk Tickets tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `helpdesk.ticket`. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/enterprise#114078
Fixed an issue where text containing percentage signs could be displayed incorrectly as double percent signs on the website. This ensures customer-facing content renders exactly as entered when no template placeholders are used.
Original PR description
`_compile_format` unconditionally escaped `%` to `%%` to protect against Python's `%`-formatting, but only appended the `% (values,)` formatting operation when `#{...}` placeholders were present. With no placeholders, the escape was never undone and `%%` leaked into the rendered output.
This went unnoticed until the introduction of paramteric t-call: https://github.com/odoo/odoo/commit/eb6e88a25050
And since we use `.translate` and `.f` directly in existing views this became apparent
Example:
```xml
<t t-call="website.s_wd_testimonial"
_testimonial_quote.translate="...by 400%."/>
```
will be rendered as `...by 400%%.` on the page.
To prevent this, we can simply check for the absence of values and simply return the repr as is if there isn't any.
Forward-Port-Of: odoo/odoo#260434This update removes the “17” tax tag from several French service tax rates where it was incorrectly applied. It helps ensure tax reporting remains accurate by keeping this tag only on goods-related taxes.
Original PR description
**Issue:** In French localization, a tax tag (i.e. "17") was wrongly added on several taxes for service by a fix: https://github.com/odoo/odoo/commit/f9237cfbb6a9ffbd0a392e4e77e097d5963a5fc3 This tax tag should only be applied on taxes for goods, not service. **Solution:** Remove the tax tag from the following taxes: - 20% EU S - 8.5% EU S - 10% EU S - 5.5% EU S - 2.1% EU S opw-5871998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260617
This update fixes an intermittent issue in the website menu automation test. It ensures the page is fully ready before entering edit mode, which makes the test more stable and reduces false failures.
Original PR description
This commit fixes a non-deterministic problem of the tour by ensuring the iframe is ready before opening an edit mode. runbot-240987 Forward-Port-Of: odoo/odoo#260309
This change prevents emails from being sent when payroll payslips are only being tested or previewed. It helps avoid confusing employees and reduces the risk of sending unintended messages before a payslip is officially issued.
Original PR description
In this commit, we prevented email sending during test print payslips. task-6147651
This update prevents an error that could appear when users open unassigned opportunities from a sales team. It also ensures the team filter is applied correctly so the unassigned leads list loads as expected.
Original PR description
Currently, an error occurs when user tries to open unassigned opportunities assigned to a team. Steps to replicate: - Install `crm` with demo. - Open `CRM > Sales > Teams` and click `Sales` team. -…
Currently, an error occurs when user tries to open unassigned opportunities assigned to a team.
Steps to replicate:
- Install `crm` with demo.
- Open `CRM > Sales > Teams` and click `Sales` team.
- Remove the `salesperson` from any lead, then return to `Teams` via breadcrumbs.
- On the kanban card for Sales, click “Unassigned Leads”.
Error:
```
File '/home/odoo/src/odoo/saas-19.2/addons/crm/models/crm_team.py', line 728, in action_open_unassigned_opportunities
context = self.env['crm.lead']._evaluate_context_from_action(action)
File '/home/odoo/src/odoo/saas-19.2/addons/crm/models/crm_lead.py', line 727, in _evaluate_context_from_action
return literal_eval(context_str)
File '/home/odoo/src/odoo/saas-19.2/odoo/_monkeypatches/ast.py', line 28, in literal_eval
return orig_literal_eval(expr)
File 'ast.py', line 66, in literal_eval
node_or_string = parse(node_or_string.lstrip(' \t'), mode='eval')
File 'ast.py', line 52, in parse
return compile(source, filename, mode, flags,
IndentationError: unexpected indent (<unknown>, line 8)
```
Cause:
- Error occurs after a recent [PR].
- As we called `literal_eval()` on the context string that we passed on to the `act_window` [1], it tries to parse the string using python like rules, the context is received as this:
```
"{\n 'search_default_team_id': [False],
\n'default_team_id': False,
\n'default_type': 'opportunity',
\n'default_user_id': 2,
\n'show_lead_gen_button': True
}\n "
^^^^^^^
```
- The extra whitespace/indentation (coming from the `act_window` context definition) makes the string invalid for strict parsing, causing `literal_eval()` to fail.
- Additionally, in the above given context string the `search_default_team_id` and `default_team_id`are both `False` because we called `_evaluate_context_from_action()` method on an empty recordset and when we try to [substitute] `active_id` with `self.id`(which is False because we dont have any record) we get another JS Error that is caused by not receiving any results for the search default on team.
Solution:
- Using `strip()` function removed the extra whitespaces.
- Passed the `team_id` through context (as we cant add new parameters to a function in stable) and assigned it in place of `active_id`.
[1]: https://github.com/odoo/odoo/blob/746ea418da2af2a6d36daea4dc544bdf3bc28495/addons/crm/views/crm_team_views.xml#L41-L48
[PR]: https://github.com/odoo/odoo/pull/240202/changes#diff-595d3dbbabdc4f766a380a320c1c1a43b143385bc7487c7275e80f76a9fbabc2R724
[substitute]: https://github.com/odoo/odoo/blob/e00dd21880c3c4e5c22d65567c700e02541f7259/addons/crm/models/crm_lead.py#L726
sentry-7404817458
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update improves the attendance dropdown by making the layout cleaner and more consistent, and it keeps the menu open or closes it more intelligently depending on the action. It also fixes how billable and non-billable timesheets are filtered, so the results better match the billing setup in place.
Original PR description
# [FIX] hr_attendance: alignment This commits revamps the attendance systray by aligning items and removing horizontal lines between attendance entries. # [FIX] hr_attendance: allow not to close systray based on condition This commits allows components inheriting from the attendance menu to conditionally close the systray. By default, the dropdown will be closed on check-in and check-out to preserve the original behaviour. See odoo/enterprise#113189 task-6088779
This update fixes several timesheet-related usability issues across attendance, helpdesk, and sales timesheet tools. It makes the timesheet panel open more smoothly after check-in, pre-fills relevant project or ticket details when available, and corrects display issues so the assistant and billable options appear as expected.
Original PR description
*: timesheet_grid,timesheet_grid_hr_attendance,helpdesk_timesheet # [FIX] timesheet_grid_hr_attendance: open timesheet systray on check-in Before this commit, the user had to re-open the systray in…
*: timesheet_grid,timesheet_grid_hr_attendance,helpdesk_timesheet # [FIX] timesheet_grid_hr_attendance: open timesheet systray on check-in Before this commit, the user had to re-open the systray in order to open the timesheet systray. Now, it is directly showed to the user upon check-in, without having the systray being closed automatically. # [FIX] web_enterprise: required project is not underlined bolder when hovered In this commit, we ensure that the border under the project in the timesheet inline form is bolder when hovered. # [FIX] timesheet_grid,helpdesk_timesheet: prefill timesheets in systray In this commit, we enable timesheets in the systray to be prefilled with project, tasks, and helpdesk tickets if the user opens the systray from any of these views, provided that the fields were empty. Further, say a project is already set, then any opened task from that project will also be populated upon opening the systray under the condition that both projects match. The same reasoning applies to helpdek tickets. # [FIX] sale_timesheet_enterprise: conditionnal class on timesheet timer After closing the systray, the 'billable' radio button ended up on a new line because the class on the timer was not correctly removed. With this commit, the button will remain on the same line as the timer, even after closing and re-opening the systray. # [FIX] sale_timesheet_enterprise: hide assistant button This commit adds conditions to display the button opening the timesheet assistant. Prior to this, the button was displayed even if the setting is not active on the user. See odoo/odoo#257930 task-6088779
Calendar meeting reminders now reach the meeting organizer as expected, including internal admin users. This fixes a case where organizers could miss in-app reminder notifications even though attendees received them.
Original PR description
Steps to reproduce: --------------------------------- 1. Install Calendar module with demo 2. For both Users: User > Preferences > Notifications > In Odoo 3. Log in through Admin > Calendar > New…
Steps to reproduce:
---------------------------------
1. Install Calendar module with demo
2. For both Users: User > Preferences > Notifications > In Odoo
3. Log in through Admin > Calendar > New meeting
4. Set a start time in the near future
5. Add Marc Demo as an attendee
6. Under Options > Reminders, add a reminder that triggers shortly before the meeting (e.g., 15 minutes)
7. Save the meeting
8. Log in as Marc Demo in another browser window
9. Wait until the reminder time is reached
Observation:
---------------------------------
The reminder notification is displayed for Marc Demo. The Administrator (Mitchell Admin) does not receive any notification.
Issue:
---------------------------------
In `_notify_next_alarm`, the domain
`('group_ids', 'in', self.env.ref('base.group_user').ids)`
was used to filter internal users. However, the admin user does not have
`base.group_user` directly in their `group_ids`, it is only present in `group_ids.all_implied_ids` (inherited through group hierarchy). This caused the admin user to be excluded from the user search, so no bus alarm notification was sent to them.
Solution:
---------------------------------
The `share` field on `res.users` correctly identifies internal users (`share=False`) vs portal/public users (`share=True`) by checking the full group hierarchy, including implied groups. This ensures the admin (and all internal users) receive alarm notifications while still excluding portal and public users.
https://github.com/odoo/odoo/blob/b261223c8e15c412a06a0d938d217bdf0ab9f9ff/odoo/addons/base/models/res_users.py#L459-L464
opw-6010337
Forward-Port-Of: odoo/odoo#255263Manually closed subscriptions will no longer reopen automatically when a payment is approved or an invoice is paid. This avoids unexpected reactivation and helps sales teams keep the intended subscription status.
Original PR description
Before this commit, when a subscription was closed manually by the salesperson, it could be reopened when a transaction was approved or an invoice paid. It could cause issue. In this case, we should not reopen automatically. task-5900481 Forward-Port-Of: odoo/enterprise#113026 Forward-Port-Of: odoo/enterprise#106487
This change lets Odoo start even when no addons folder exists yet in a new, empty project repository. It removes an unnecessary validation error so teams can set up and begin creating modules without being blocked at launch.
Original PR description
Initialize a new empty git repository where you are going to vide-code some new Odoo modules. Because the repository is empty (no addon yet) the CLI fails with an "option --addons-path: the path <path> is not a valid addons directory". This makes vide-coder sad, and bigrams want vide-coders to be happy, so drop the sanity-check and also accept empty addons. Forward-Port-Of: odoo/odoo#259007 Forward-Port-Of: odoo/odoo#256913
Point of Sale now correctly finds products when a GS1 barcode includes a leading zero in its GTIN-14 format. This prevents valid items from being missed at scan time and helps cashiers continue checkout without manual workarounds.
Original PR description
When scanning a GS1 barcode whose GTIN-14 has a leading zero (e.g. a product stored with EAN-13 "5400000002649" is encoded as GTIN-14 "05400000002649"), the product lookup in _getProductByBarcode failed because the exact string did not match the stored barcode. opw-6117948 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259199
This update makes the Point of Sale work more reliably on iPhone and Safari when the app is sent to the background and later resumed. It helps prevent database connection failures that could otherwise interrupt the POS experience or require a refresh.
Original PR description
On iOS/Safari, the WebKit IDB server process can be killed by the OS (e.g. due to memory pressure when the app is backgrounded), resulting in an UnknownError: "Connection to Indexed Database server lost". Additionally, returning from background can leave the connection in an InvalidStateError "closing" state while this.db remains non-null. opw-5121896 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259697 Forward-Port-Of: odoo/odoo#253943
This update brings back the vertical spacing in the dropdown list used for menu selections. It improves readability and usability by making the options easier to scan without affecting the behavior of grouped items.
Original PR description
Recent structural changes added `p-0` to the menu class, removing the vertical padding from the dropdown. Rather than padding the scroll container directly (which would conflict with sticky group headers), apply `margin-top/bottom` on the first/last children of `.o_select_menu-choices` so the spacing scrolls naturally without creating a gap items could bleed through when a group header is stuck. task-6095912 Forward-Port-Of: odoo/odoo#258929
Vendor bills imported from XML now correctly keep the pension fund tax linked, even when the VAT rate is 0.00. This prevents missing tax assignments and helps ensure imported bills are recorded accurately and compliantly.
Original PR description
### Issue before this commit: When importing vendor bills from XML files containing a pension fund (e.g., type TC08), the pension fund tax was not correctly applied to the invoice lines. As a result,…
### Issue before this commit: When importing vendor bills from XML files containing a pension fund (e.g., type TC08), the pension fund tax was not correctly applied to the invoice lines. As a result, the imported bills were missing the expected tax association. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Set the pension fund type as TC08 (or another one is also fine) in the Advanced Tab of 4% F.Pens. tax 3. Try to upload an XML for vendor bills with a TC08 tax 4. The tax is not associated ### Cause of the issue: The issue was caused by the handling of the VAT rate (AliquotaIVA) when its value was 0.00. The code incorrectly treated this value as falsy, preventing the correct identification and assignment of the pension fund tax during the import process. ### Reason to introduce the fix: The fix ensures that a VAT rate of 0.00 is correctly interpreted as a valid value rather than being ignored. This allows the system to properly detect and apply the pension fund tax during XML import, ensuring accurate tax assignment and compliance with expected accounting behavior. opw-6093352 Forward-Port-Of: odoo/odoo#258341
21 changes
New functionality added to Odoo
This update adds the ability to export Slovak VAT reports in XML format, aligning with government regulations. This ensures accurate and compliant reporting for our Slovakian clients, simplifying their tax filing processes. It backports a feature previously introduced in the saas-19.1 release.
Original PR description
Backported the XML export for Slovak VAT report introduced in saas-19.1 (commit https://github.com/odoo/enterprise/commit/ab6ec9b8bc568e9c88de4556c685b721f001680c7) Related: https://github.com/odoo/odoo/pull/260337 task-6139318 Forward-Port-Of: odoo/enterprise#114448
Enhancements to existing features
This update adds a Slovak VAT tax report, aligning with official DPHv25 form requirements. It includes mappings for key tax scenarios like bad debts and reverse charges, ensuring accurate reporting for Slovak businesses. This improves compliance and reporting capabilities within Odoo.
Original PR description
Backported the Slovak tax report introduced in saas-19.1 (commit 32afab28dacf79e200eef27ee10c66101e275e07) along with its related fix (commit 6414da3c4eeef23ca86ce70c05b426878602bb4d). Additionally, included a small adaptation commit to ensure the report works properly in v19. Related: https://github.com/odoo/enterprise/pull/114448 task-6139318 Forward-Port-Of: odoo/odoo#260337
Resolved issues and error corrections
This update fixes an issue in several localized tax reports where an old report-crossing setting was left behind during an upgrade. As a result, affected reports can now open correctly again in newer Odoo versions.
Original PR description
- This aggregation expression used to have 'cross_report' as subformula. Though, it was useless (since the aggregation only uses term from the same report), and the subformula was removed from the…
- This aggregation expression used to have 'cross_report' as subformula. Though, it was useless (since the aggregation only uses term from the same report), and the subformula was removed from the data file without explicitly resetting it to False. This became a problem in 18.3, because the cross_report syntax changes. Because of that, a migrated report failed to open, since it still was using the old syntax on that expression. We fix that by explicitly emptying the subformula. see https://github.com/odoo/odoo/pull/193106 ```python3 Opération invalide Dans le rapport "Section I (LU)", à la ligne "472 - Autres Ventes / Recettes", avec le libellé "balance", Le format de l'expression de rapport croisé est invalide. Format attendu : cross_report(<report_id>|<xml_id>) Exemple : cross_report(my_module.my_report) ou cross_report(123) ``` opw-6103170 upg-4166654(lu) upg-4163103(it) upg-4175631(ug) upg-4177165(es) 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#258826
Calendar reminder notifications now properly go to the meeting organizer as well as other internal users. This fixes a case where the administrator could be missed, so reminders are more reliable and consistent for everyone inside the company.
Original PR description
Steps to reproduce: --------------------------------- 1. Install Calendar module with demo 2. For both Users: User > Preferences > Notifications > In Odoo 3. Log in through Admin > Calendar > New…
Steps to reproduce:
---------------------------------
1. Install Calendar module with demo
2. For both Users: User > Preferences > Notifications > In Odoo
3. Log in through Admin > Calendar > New meeting
4. Set a start time in the near future
5. Add Marc Demo as an attendee
6. Under Options > Reminders, add a reminder that triggers shortly before the meeting (e.g., 15 minutes)
7. Save the meeting
8. Log in as Marc Demo in another browser window
9. Wait until the reminder time is reached
Observation:
---------------------------------
The reminder notification is displayed for Marc Demo. The Administrator (Mitchell Admin) does not receive any notification.
Issue:
---------------------------------
In `_notify_next_alarm`, the domain
`('group_ids', 'in', self.env.ref('base.group_user').ids)`
was used to filter internal users. However, the admin user does not have
`base.group_user` directly in their `group_ids`, it is only present in `group_ids.all_implied_ids` (inherited through group hierarchy). This caused the admin user to be excluded from the user search, so no bus alarm notification was sent to them.
Solution:
---------------------------------
The `share` field on `res.users` correctly identifies internal users (`share=False`) vs portal/public users (`share=True`) by checking the full group hierarchy, including implied groups. This ensures the admin (and all internal users) receive alarm notifications while still excluding portal and public users.
https://github.com/odoo/odoo/blob/b261223c8e15c412a06a0d938d217bdf0ab9f9ff/odoo/addons/base/models/res_users.py#L459-L464
opw-6010337
Forward-Port-Of: odoo/odoo#255263We fixed an issue where opening a shared helpdesk ticket could crash if the original message author had been deleted. The ticket now opens normally, even when some author details are no longer available, improving reliability for shared links.
Original PR description
Currently, an error occurs when opening a shared helpdesk ticket link if the message author has been deleted. **Steps to Reproduce:(v19.2)** - Install Contacts and Helpdesk modules (with demo data). - Log in as "**Marc Demo**". - Create a helpdesk ticket and send a message via the chatter. - Log in as **Admin**. - Delete the demo user and the related partner from Contacts. - Go to Helpdesk > All Tickets and open the created ticket. - Click "**Share Ticket**" and open the generated link in another browser. Error: `ValueError - Expected singleton: res.partner()` **Cause:** When the partner linked to `message.author_id` is deleted, the recordset becomes empty, which raises a singleton error. Fix: This commit ensures that the author details are only included when the message author exists. sentry-7337698605 Forward-Port-Of: odoo/odoo#260332 Forward-Port-Of: odoo/odoo#254175
The refusal wizard now avoids automatically selecting email templates that have been archived. This prevents outdated templates from appearing pre-filled when users refuse an applicant, helping keep the workflow clearer and less error-prone.
Original PR description
Pre-requisites: --------------- 1. Create or duplicate any `hr.applicant` email template. 2. Archive the newly created template. 3. Archive the email template linked to a refuse reason. Steps to…
Pre-requisites: --------------- 1. Create or duplicate any `hr.applicant` email template. 2. Archive the newly created template. 3. Archive the email template linked to a refuse reason. Steps to reproduce: ------------------------- 1. Install hr_recruitment. 4. Go to Recruitment > Applications > All Applications and open an applicant. 5. Click on the "Refuse" button to open the refuse wizard. 6. Click on the "Email Template" and click on 'Search More' 7. Observe available templates Issue: ------- If a refuse reason is linked to an archived email template, the wizard automatically pre-fills that archived template Cause: ---------- The `_compute_template_id` method automatically assigns the template from the refuse reason without checking whether the template is active, which allows archived templates to be pre-filled in the wizard. https://github.com/odoo/odoo/blob/aa2a7c0e5a5de970cdb8f6a7ba9f02ad75cf5078/addons/hr_recruitment/wizard/applicant_refuse_reason.py#L91-L96 Solution: ----------- - Update `_compute_template_id` to ensure only active templates are automatically assigned. opw-5974244 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257580 Forward-Port-Of: odoo/odoo#251186
This change stops combo products from being selected on the mobile sales order line form. It prevents empty zero-priced lines from being created without their required child items, reducing errors and avoiding incomplete orders.
Original PR description
Combo products bypasses the configurator in mobile view, resulting in a 0-price line with no child lines. Exclude them via domain on the field. opw-5999935 Forward-Port-Of: odoo/odoo#260056 Forward-Port-Of: odoo/odoo#256790
Project chatter will no longer automatically post tracking messages when a linked Sales Order changes status. This reduces unnecessary activity in the record history and keeps the chatter focused on more relevant project updates.
Original PR description
Before this commit: - The chatter on the Project record tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `project.project`, `project.task` models. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/odoo#258549
Helpdesk tickets will no longer automatically post chatter messages when the linked Sales Order changes status. This reduces noisy activity in ticket conversations and keeps the discussion focused on customer support updates.
Original PR description
Before this commit: - The chatter on Helpdesk Tickets tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `helpdesk.ticket`. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/enterprise#114078
A display issue could turn normal percent signs into doubled percent signs in rendered website content. This fix ensures text is shown exactly as entered when no placeholders are involved, preventing awkward or incorrect page copy.
Original PR description
`_compile_format` unconditionally escaped `%` to `%%` to protect against Python's `%`-formatting, but only appended the `% (values,)` formatting operation when `#{...}` placeholders were present. With no placeholders, the escape was never undone and `%%` leaked into the rendered output.
This went unnoticed until the introduction of paramteric t-call: https://github.com/odoo/odoo/commit/eb6e88a25050
And since we use `.translate` and `.f` directly in existing views this became apparent
Example:
```xml
<t t-call="website.s_wd_testimonial"
_testimonial_quote.translate="...by 400%."/>
```
will be rendered as `...by 400%%.` on the page.
To prevent this, we can simply check for the absence of values and simply return the repr as is if there isn't any.
Forward-Port-Of: odoo/odoo#260434This update removes an incorrect tax tag from several French service taxes. It helps ensure tax reporting is applied only where intended, reducing the risk of mistaken calculations or declarations.
Original PR description
**Issue:** In French localization, a tax tag (i.e. "17") was wrongly added on several taxes for service by a fix: https://github.com/odoo/odoo/commit/f9237cfbb6a9ffbd0a392e4e77e097d5963a5fc3 This tax tag should only be applied on taxes for goods, not service. **Solution:** Remove the tax tag from the following taxes: - 20% EU S - 8.5% EU S - 10% EU S - 5.5% EU S - 2.1% EU S opw-5871998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260617
This update resolves an issue where the Odoo system couldn't correctly handle the Turkey timezone after a recent Ubuntu 24.04 update, which moved timezone data. The fix adds a fallback mechanism to ensure accurate timezone calculations, preventing errors during database upgrades. Additionally, the update addresses timezones in America/Catamarca and America/Godthab that were previously unsupported.
Original PR description
**[FIX] handle Turkey timezone when tzdata-legacy not installed** In #236660 we switched from pytz to zoneinfo. The library `pytz` has `Turkey` in **pytz.all_timezones_set**. On the other hand…
**[FIX] handle Turkey timezone when tzdata-legacy not installed**
In #236660 we switched from pytz to zoneinfo.
The library `pytz` has `Turkey` in **pytz.all_timezones_set**.
On the other hand starting from ubuntu 24.04 as tzdata was split and `Turkey` was [moved](https://documentation.ubuntu.com/release-notes/24.04/#tzdata-package-split) out of tzdata to tzdata-legacy.
If we run a db which has reference to `Turkey` timezone, on a server which is ubuntu 24.04 and tzdata-legacy not installed, we will get an error as we did not have fallback for `Turkey` while we have for `Türkiye`. Because zoneinfo will not have `Turkey` in `zoneinfo.available_timezones()`
Issue was discovered during upgrade of db which has res.partners with timezone=`Turkey` from 19.0 to saas~19.1. The upgrading docker container was nobel and it did not have tzdata-legacy.
For fixing the issue we added fallback for `Turkey`.
Tbh I do not think we need a fallback for `Türkiye` but I wanted to not change the old behaviour.
###
**[FIX] handle America/{Catamarca,Godthab} timezones**
As we moved from `pytz` to `zoneinfo` in **saas~19.1**
we have 2 more timezones which were existing in `pytz`
but not in `tzdata` adn we do not have fallback for them.
They are in `tzdata-legacy`:
- America/Catamarca
- America/Godthab
We added fallback for them.
We already have a failing upgrade request because of
America/Catamarca.
Turkey:
```
File "/home/odoo/src/odoo/saas-19.1/addons/calendar/models/calendar_event.py", line 742, in _compute_field_value
return super()._compute_field_value(field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/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.1/odoo/orm/models.py", line 4271, in _compute_field_value
determine(field.compute, self)
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/fields.py", line 83, in determine
return needle(*args)
^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/addons/calendar/models/calendar_event.py", line 503, in _compute_recurrence
event_values = event._get_recurrence_params()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/addons/calendar/models/calendar_event.py", line 1341, in _get_recurrence_params
event_date = self._get_start_date()
^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/addons/calendar/models/calendar_event.py", line 1573, in _get_start_date
return start.replace(tzinfo=UTC).astimezone(ZoneInfo(self.event_tz)).date()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/odoo/_monkeypatches/zoneinfo.py", line 130, in __new__
z = super().__new__(cls, key)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/zoneinfo/_common.py", line 24, in load_tzdata
raise ZoneInfoNotFoundError(f"No time zone found with key {key}")
zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key Turkey'
```
Catamarca:
```
Traceback (most recent call last):
File "/tmp/tmpm0v0h90i/migrations/base/tests/test_mock_crawl.py", line 335, in crawl_menu
self.mock_action(action_vals)
File "/tmp/tmpm0v0h90i/migrations/base/tests/test_mock_crawl.py", line 348, in mock_action
return self.mock_act_window(action)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/tmpm0v0h90i/migrations/base/tests/test_mock_crawl.py", line 508, in mock_act_window
mock_method(model, view, fields_list, domain, group_by)
File "/tmp/tmpm0v0h90i/migrations/base/tests/test_mock_crawl.py", line 541, in mock_view_form
[data] = record.read(fields_list)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/models.py", line 2735, in read
self._origin.fetch(fields)
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/models.py", line 3067, in fetch
fetched.mapped(field_name)
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/models.py", line 5479, in mapped
return [getter(record) for record in records]
^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/fields.py", line 1794, in __get__
self.compute_value(recs)
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/fields.py", line 1965, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/models.py", line 4271, in _compute_field_value
determine(field.compute, self)
File "/home/odoo/src/odoo/saas-19.1/odoo/orm/fields.py", line 83, in determine
return needle(*args)
^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/odoo/addons/base/models/res_users.py", line 455, in _compute_tz_offset
user.tz_offset = datetime.datetime.now(ZoneInfo(user.tz or 'UTC')).strftime('%z')
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.1/odoo/_monkeypatches/zoneinfo.py", line 130, in __new__
z = super().__new__(cls, key)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/zoneinfo/_common.py", line 24, in load_tzdata
raise ZoneInfoNotFoundError(f"No time zone found with key {key}")
zoneinfo._common.ZoneInfoNotFoundError: 'No time zone found with key America/Catamarca'
```
tbg-2529
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 timesheet forecasts incorrectly included planned hours on public holidays. The fix ensures the system accurately excludes holiday periods, regardless of whether they're linked to a specific calendar, and accounts for timezone differences to prevent date shifting.
Original PR description
### Steps to reproduce: - Install project_timesheet_forecast module - Configure your database to have a far timezone (Montevideo/Uruguay in my case) - Create a public holiday starts from 12AM to…
### Steps to reproduce: - Install project_timesheet_forecast module - Configure your database to have a far timezone (Montevideo/Uruguay in my case) - Create a public holiday starts from 12AM to 11:59PM with a calendar - Create a planning slot for a resource that overlap with the public holiday - Check the Timesheets / Planning analysis report - Group by employees > day **- Check the date of the public holiday and notice there are still planned hours shown** - Remove the calendar from the public holidays that we created previously - Check the report once again **- Notice the day of the public holiday and the day after has no planned hours** ### Cause: In the query we are using to exclude the leave days from the report we only exclude the ones that has calendar_id assigned, not taking into consideration that some of the public holiday are general and is not applied to just one working schedule. Also if we have a leave starting midnight to 11:59PM since we store dates in database as UTC for timezone like Uruguay's one it will shift the end with one day which will introduce inconsistencies ### Fix: We check if the calendar_id is null on the resource_calendar_leaves and make sure we take timezone of the resource into account when checking the dates of the leaves. opw-5027070 Forward-Port-Of: odoo/enterprise#111846
This update fixes an issue where a subscription could be automatically reopened after a salesperson manually closed it. Previously, approvals or payments triggered reopening, leading to potential inconsistencies. Now, subscriptions remain closed after manual closure, ensuring accurate subscription management.
Original PR description
Before this commit, when a subscription was closed manually by the salesperson, it could be reopened when a transaction was approved or an invoice paid. It could cause issue. In this case, we should not reopen automatically. task-5900481 Forward-Port-Of: odoo/enterprise#113026 Forward-Port-Of: odoo/enterprise#106487
This update removes an outdated requirement for country information on payment tokens used for subscription invoices. Previously, this restriction caused processing issues, but modern payment providers now support invoices without country details. This change improves invoice processing reliability and efficiency.
Original PR description
Before this commit, a country was mantadory on the payment token when it was used to pay invoices of subscriptions. This behavior was fetched back from internal code in 15.3. This issue was not visible until recently. Some token are fine without country, the provider allows it but the cron fails to process the sale order when the contract is processed. THis commit remove that old constraint. opw-5268156 task-5349998 Forward-Port-Of: odoo/enterprise#100166
This update prevents customers without a portal account from seeing the 'Pay Now' button in follow-up emails. This avoids confusion and ensures customers aren't directed to a portal they can't access, streamlining the invoicing process.
Original PR description
If a customer has no portal account, the pay now button added to follow-up emails won't allow them to access any invoices on the portal. Even if they register afterwards, a separate account will be created and they won't have access to those invoices. To avoid confusion, this commit hides the pay now button when the customer has no portal account. task-6075621 Forward-Port-Of: odoo/enterprise#112891
This update resolves a problem where confirming deliveries for kit products would trigger errors. The fix ensures that kit moves are correctly processed during delivery validation, preventing tracebacks and allowing deliveries to be confirmed smoothly. This ensures accurate stock accounting and avoids disruptions in the order fulfillment process.
Original PR description
**Issue**: Making a product a kit could prevent confirming deliveries. **Steps to reproduce**: - Make sure the account application is installed - Create a product P without kit - Create a SO and…
**Issue**: Making a product a kit could prevent confirming deliveries. **Steps to reproduce**: - Make sure the account application is installed - Create a product P without kit - Create a SO and confirm it - Make the product P a kit - Validate the delivery associated to the SO -> A traceback occurs: the record does not exist anymore **Cause**: While confirming the delivery: https://github.com/odoo/odoo/blob/a253cff9039fcf729a9922b119acad5ec7c7a0bd/addons/stock_account/models/stock_move.py#L168 It first filters which moves are out (`moves_out`). On the move associated with product P, since the kit is not exploded yet: https://github.com/odoo/odoo/blob/a253cff9039fcf729a9922b119acad5ec7c7a0bd/addons/stock_account/models/stock_move.py#L172 Then explodes the kit: https://github.com/odoo/odoo/blob/a253cff9039fcf729a9922b119acad5ec7c7a0bd/addons/stock_account/models/stock_move.py#L174 https://github.com/odoo/odoo/blob/ea18f34a48d61350f80c79894bef66bf02840bfc/addons/mrp/models/stock_move.py#L357-L361 By doing so, the original move associated to the product P are deleted: https://github.com/odoo/odoo/blob/ea18f34a48d61350f80c79894bef66bf02840bfc/addons/mrp/models/stock_move.py#L399 Thus, `moves_out` contains moves that no longer exist, and eventually, and eventually while accessing `product_id`: https://github.com/odoo/odoo/blob/a253cff9039fcf729a9922b119acad5ec7c7a0bd/addons/stock_account/models/stock_move.py#L179 A traceback is thrown **Aditionnal information** Validating a delivery of a kit product whose moves were not exploded will trigger their explosion and require a second validation. Therefore, no stock valuation errors will be created. opw-6063602 Forward-Port-Of: odoo/odoo#258403
This update resolves an issue preventing developers from creating new, empty Odoo repositories for testing and development. The change relaxes a validation check, allowing empty repositories to be created without errors, which improves the development workflow. This ensures developers can easily start new projects without encountering initial setup problems.
Original PR description
Initialize a new empty git repository where you are going to vide-code some new Odoo modules. Because the repository is empty (no addon yet) the CLI fails with an "option --addons-path: the path <path> is not a valid addons directory". This makes vide-coder sad, and bigrams want vide-coders to be happy, so drop the sanity-check and also accept empty addons. Forward-Port-Of: odoo/odoo#259007 Forward-Port-Of: odoo/odoo#256913
This update fixes an issue where scanning GS1 barcodes with leading zeros (like EAN-13 codes) wasn't working correctly. The fix ensures that products are accurately identified when scanning these barcodes, preventing errors during sales transactions. This improves the reliability of the Point of Sale system.
Original PR description
When scanning a GS1 barcode whose GTIN-14 has a leading zero (e.g. a product stored with EAN-13 "5400000002649" is encoded as GTIN-14 "05400000002649"), the product lookup in _getProductByBarcode failed because the exact string did not match the stored barcode. opw-6117948 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259199
This update resolves an issue where the Point of Sale app on iOS Safari would unexpectedly crash due to a lost connection to its local database. The fix prevents data loss and improves the overall stability of the app, particularly when the app is in the background. This ensures a smoother and more reliable experience for users.
Original PR description
On iOS/Safari, the WebKit IDB server process can be killed by the OS (e.g. due to memory pressure when the app is backgrounded), resulting in an UnknownError: "Connection to Indexed Database server lost". Additionally, returning from background can leave the connection in an InvalidStateError "closing" state while this.db remains non-null. opw-5121896 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259697 Forward-Port-Of: odoo/odoo#253943
This update fixes an issue where the system wasn't correctly applying pension fund tax (TC08) when the VAT rate was 0.00 during XML import. The fix ensures accurate tax assignment, improving compliance and preventing missing tax associations in imported vendor bills.
Original PR description
### Issue before this commit: When importing vendor bills from XML files containing a pension fund (e.g., type TC08), the pension fund tax was not correctly applied to the invoice lines. As a result,…
### Issue before this commit: When importing vendor bills from XML files containing a pension fund (e.g., type TC08), the pension fund tax was not correctly applied to the invoice lines. As a result, the imported bills were missing the expected tax association. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Set the pension fund type as TC08 (or another one is also fine) in the Advanced Tab of 4% F.Pens. tax 3. Try to upload an XML for vendor bills with a TC08 tax 4. The tax is not associated ### Cause of the issue: The issue was caused by the handling of the VAT rate (AliquotaIVA) when its value was 0.00. The code incorrectly treated this value as falsy, preventing the correct identification and assignment of the pension fund tax during the import process. ### Reason to introduce the fix: The fix ensures that a VAT rate of 0.00 is correctly interpreted as a valid value rather than being ignored. This allows the system to properly detect and apply the pension fund tax during XML import, ensuring accurate tax assignment and compliance with expected accounting behavior. opw-6093352 Forward-Port-Of: odoo/odoo#258341
1 change
Resolved issues and error corrections
Helpdesk tickets will no longer automatically record chatter messages when the linked sales order’s status changes. This reduces unnecessary activity in the ticket conversation and keeps the discussion focused on support work.
Original PR description
Before this commit: - The chatter on Helpdesk Tickets tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `helpdesk.ticket`. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/enterprise#114078
5 changes
Resolved issues and error corrections
This change fixes a small text typo in the website opening hours snippet, correcting the time label from "am" to "pm". It improves clarity for visitors so business hours are displayed accurately.
Original PR description
am to pm Forward-Port-Of: odoo/odoo#260579
This update fixes a Calendar reminder issue where the meeting organizer could miss in-app notifications. Internal users, including administrators, now reliably receive alarm alerts while portal and public users remain excluded.
Original PR description
Steps to reproduce: --------------------------------- 1. Install Calendar module with demo 2. For both Users: User > Preferences > Notifications > In Odoo 3. Log in through Admin > Calendar > New…
Steps to reproduce:
---------------------------------
1. Install Calendar module with demo
2. For both Users: User > Preferences > Notifications > In Odoo
3. Log in through Admin > Calendar > New meeting
4. Set a start time in the near future
5. Add Marc Demo as an attendee
6. Under Options > Reminders, add a reminder that triggers shortly before the meeting (e.g., 15 minutes)
7. Save the meeting
8. Log in as Marc Demo in another browser window
9. Wait until the reminder time is reached
Observation:
---------------------------------
The reminder notification is displayed for Marc Demo. The Administrator (Mitchell Admin) does not receive any notification.
Issue:
---------------------------------
In `_notify_next_alarm`, the domain
`('group_ids', 'in', self.env.ref('base.group_user').ids)`
was used to filter internal users. However, the admin user does not have
`base.group_user` directly in their `group_ids`, it is only present in `group_ids.all_implied_ids` (inherited through group hierarchy). This caused the admin user to be excluded from the user search, so no bus alarm notification was sent to them.
Solution:
---------------------------------
The `share` field on `res.users` correctly identifies internal users (`share=False`) vs portal/public users (`share=True`) by checking the full group hierarchy, including implied groups. This ensures the admin (and all internal users) receive alarm notifications while still excluding portal and public users.
https://github.com/odoo/odoo/blob/b261223c8e15c412a06a0d938d217bdf0ab9f9ff/odoo/addons/base/models/res_users.py#L459-L464
opw-6010337
Forward-Port-Of: odoo/odoo#255263Project chatter will no longer automatically log updates to the linked Sales Order’s status. This reduces unnecessary notifications and keeps project communication focused on information that is directly relevant to the project team.
Original PR description
Before this commit: - The chatter on the Project record tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `project.project`, `project.task` models. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/odoo#258549
Helpdesk tickets will no longer automatically post chatter messages when the linked Sales Order changes status. This reduces unnecessary noise in the ticket history and makes the conversation easier to follow for support teams.
Original PR description
Before this commit: - The chatter on Helpdesk Tickets tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `helpdesk.ticket`. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/enterprise#114078
This update adjusts internal test checks so they recognize new Python 3.14 class attributes created by the updated annotation system. It helps keep Odoo’s test suite working correctly on newer Python versions without affecting normal business features.
Original PR description
Since Python 3.14 (PEP 649), class annotations are evaluated lazily. This introduces two new internal attributes to the class namespace: - `__annotate_func__`: The function that computes the annotations. - `__annotations_cache__`: The cache for the computed annotations. This commit adds these attributes to the TransactionCase's ignored internal attributes checker. Note: this PR is a follow-up of https://github.com/odoo/odoo/pull/247151 Reference: - https://peps.python.org/pep-0649/ Forward-Port-Of: odoo/odoo#260573
12 changes
Enhancements to existing features
The Ecuador invoice report now places customer information in a separate table to avoid layout issues when there is more data to display. This makes the invoice easier to read and helps prevent overlapping or cramped information on printed reports.
Original PR description
EC invoice custom report had some visual issues due to the limited space where customer information is shown, which was more obvious once the customer information started to grow. To fix this, the customer info is moved to a new table. task-6093976
After databases are synchronized with Odoo.com, the system now tries to create a local API key for each database that does not already have one. This reduces reliance on the global key and can save time during database access, improving overall sync performance.
Original PR description
Before this commit, databases fetched from Odoo's SaaS were contacted using the global API key, which is more costly than using a key local to each database. Avoiding the call from the server to Odoo to check the foreign API key can spare about 500ms on each database where this key is not in the LRU. With this commit, after the synchronization with Odoo.com, we try to generate an API key on each database that doesn't have one yet. To do so, it relies on the API introduced by odoo/odoo#246118. Forward-Port-Of: odoo/enterprise#114406 Forward-Port-Of: odoo/enterprise#106372
Resolved issues and error corrections
This update corrects a typo and adjusts the visual styling in the VOIP dashboard. It improves readability and polish without changing how the dashboard works.
Original PR description
task-6132220 Forward-Port-Of: odoo/enterprise#114324
This update fixes problems that appeared after benefits were moved in the payroll and contract salary areas. It helps ensure employee salary and payroll information displays and behaves correctly after the change.
Original PR description
…fits Task: 6141770
This change fixes an unstable automated test in Belgian payroll by freezing the date used during the test. It prevents the test from randomly passing or failing as the calendar year changes, improving reliability of nightly builds.
Original PR description
The test was failing intermittently in nightly builds that run at a date in the next year (e.g.: 2027-04-20). The issue was that the student's age is calculated at runtime using : - When the student is age 19 (2026): min wage = 2057.87 < 2100 → PASS - When the student is age 20 (2027): min wage = 2136.84 > 2100 → FAIL task-6144986 Forward-Port-Of: odoo/enterprise#114594
This change prevents an error that could appear when creating or editing a salary adjustment if the start date is not yet set. As a result, payroll users can complete the adjustment flow without encountering an unexpected traceback.
Original PR description
This task guard against falsy date_start in _compute_estimated_end to avoid adding a relativedelta to False, fixing a traceback appearing during onchange. task-6139538 Forward-Port-Of: odoo/enterprise#114332
This change fixes an error that could appear when users click certain cells in the Trial Balance report, specifically for Undistributed Profits/Losses. It ensures the report opens correctly instead of failing with a missing data error, improving reliability when reviewing accounting balances.
Original PR description
This error occurs when clicking on any cell for `Undistributed Profits/Losses` in the `Trial Balance` report. Steps to reproduce: - Install `Accounting` module - Create `Journal Entry` with past-year…
This error occurs when clicking on any cell for `Undistributed Profits/Losses` in the `Trial Balance` report. Steps to reproduce: - Install `Accounting` module - Create `Journal Entry` with past-year `Accounting Date` (eg: 31-12-2025) and include one `Journal Items` for `Undistributed Profits/Losses` - Open `Trail Balance` report and click on any cell for `Undistributed Profits/Losses` Traceback: `KeyError: 'report_line_id'` Before this [commit], we were returning fields with `null/None` values. After the commit, fields containing `null/None` [value] are removed, and only fields with valid values are returned. As a result, when the `dispatch_report_action` function is called, the `report_line_id` is missing in `params`. [commit]: https://github.com/odoo/enterprise/pull/102808/changes/b92dc397bef029472a40223f51b611cdf5b631dc [value]: https://github.com/odoo/enterprise/blob/626b8157bcea2e3843cd9d5d0c0036e302b8e5ce/account_reports/utils/report_data_objects.py#L42-L43 sentry-7372351871 opw-6119913 Forward-Port-Of: odoo/enterprise#113421
This change prevents an error that could occur when opening or retrieving account report information. It updates the report code to use the correct method for the new data structure, so reports load normally again.
Original PR description
Currently, an error occurs when retrieving account report information. ``` File "/home/odoo/odoo18/enterprise/account_reports/models/account_report.py", line 1475, in _create_hierarchy…
Currently, an error occurs when retrieving account report information.
```
File "/home/odoo/odoo18/enterprise/account_reports/models/account_report.py", line 1475, in _create_hierarchy
render_lines(root_account_groups, current_level, root_line_id, skip_no_group=False)
File "/home/odoo/odoo18/enterprise/account_reports/models/account_report.py", line 1373, in render_lines
child_line.update
^^^^^^^^^^^^^^^^^
AttributeError: 'AccountReportLineData' object has no attribute 'update'
```
After the [recent commit], all lines, columns, format_params, and annotations are converted into custom objects (AccountReportLineData). However, the code still attempts to use the update() method on these objects, which raises an error [1] since AccountReportLineData does not have an update method.
This commit ensures that the update_value() method is used to update AccountReportLineData objects, as intended, like here [2].
[recent commit]: https://github.com/odoo/enterprise/commit/6608d5c21a7fb9d57786c2a7618b878e244bd420
[1]- https://github.com/odoo/enterprise/blob/cde4e05de82476655764f8c9fe8734416d4a35bf/account_reports/models/account_report.py#L1373-L1377
[2]- https://github.com/odoo/enterprise/blob/cde4e05de82476655764f8c9fe8734416d4a35bf/account_reports/models/account_report.py#L6565
sentry-7403925422
Forward-Port-Of: odoo/enterprise#113668This change ensures that when a salesperson manually closes a subscription, it stays closed even if a payment is later approved or an invoice is paid. This avoids accidentally reopening subscriptions that were intentionally ended, preventing confusion and billing issues.
Original PR description
Before this commit, when a subscription was closed manually by the salesperson, it could be reopened when a transaction was approved or an invoice paid. It could cause issue. In this case, we should not reopen automatically. task-5900481 Forward-Port-Of: odoo/enterprise#113026 Forward-Port-Of: odoo/enterprise#106487
This update ensures that changes to salary information within the salary configurator correctly update related calculations for mobility budgets. Previously, changes outside this specific context could cause inconsistencies. This change improves the accuracy of budget calculations and avoids unexpected behavior.
Original PR description
For consistency purposes, we only trigger the inverse on the mobility budget computation if we are in the context of the salary configurator. Changing the wage in the back end or changing the employer cost should only touch the wage and not other benefits Forward-Port-Of: odoo/enterprise#112510 Forward-Port-Of: odoo/enterprise#111828
This update resolves performance issues and crashes when generating the VAT Books Excel report for large invoices. By optimizing memory usage and query execution, the report now runs efficiently even with extensive data, significantly reducing server load and improving export times.
Original PR description
Related Ticket: https://www.odoo.com/odoo/project/49/tasks/6037414 ### Description of the issue/feature this PR addresses: Generating the "VAT Books" Excel report causes severe performance…
Related Ticket: https://www.odoo.com/odoo/project/49/tasks/6037414 ### Description of the issue/feature this PR addresses: Generating the "VAT Books" Excel report causes severe performance bottlenecks and MemoryError crashes on databases with a massive volume of invoice lines. This PR introduces strict memory management and query optimizations to prevent server crashes and drastically speed up the XLSX export process. ### Current behavior before PR: When exporting the VAT Books report for a large dataset, the system attempts to hold the entire workbook structure in RAM. Additionally, the ORM unnecessarily prefetches fields when iterating over the account.move.line recordset and performs excess sub-queries to look up move_type for journal entries. This combination results in massive memory consumption, slow load times, and eventual server crashes. ### Desired behavior after PR is merged: The VAT Books report generates successfully and efficiently, even on massive databases, with a significantly reduced memory footprint. Specifically: - The ORM bypasses cache bloat by disabling field prefetching (prefetch_fields=False) during the recordset iteration. - The query execution is optimized by changing the search domain from move_type to move_id.move_type, leveraging the existing join table rather than triggering expensive sub-queries. ### Benchmark: The model is iterating through ~1.1M journal items when generating the full report. For Memory: | # Input Data | Before PR | After PR| | -------- | -------- | -------- | | ~7,800 journal items | 1.4GB| 202 MB | | ~32,000 journal items | MemoryError | 278 MB | | ~141,500 journal items | MemoryError | 760 MB | | ~1.1M journal items | MemoryError | 1.4 GB | For Speed: | # Input Data | Before PR | After PR| | -------- | -------- | -------- | | ~7,800 journal items | 2 min | 1.5s | | ~32,000 journal items | MemoryError | 4s | | ~141,500 journal items | MemoryError | 12s | | ~1.1M journal items | MemoryError | 56s | ### Reference opw-6037414 ----------------------------------------------------------------- I confirm I have signed the CLA and read the PR guidelines at [www.odoo.com/submit-pr](http://www.odoo.com/submit-pr) Forward-Port-Of: odoo/enterprise#112230
Code cleanup and technical improvements
This change modernizes parts of the web editing experience by removing reliance on an older JavaScript library in most add-ons. It helps keep the codebase easier to maintain and better prepared for future updates, with no expected impact on everyday business use.
8 changes
New functionality added to Odoo
This update adds the ability to export Slovak VAT reports in XML format, aligning with government requirements. This ensures accurate reporting for Slovak businesses using Odoo Enterprise, improving compliance and data accuracy. The change was backported from a recent Odoo release.
Original PR description
Backported the XML export for Slovak VAT report introduced in saas-19.1 (commit https://github.com/odoo/enterprise/commit/ab6ec9b8bc568e9c88de4556c685b721f001680c7) Related: https://github.com/odoo/odoo/pull/260337 task-6139318
Resolved issues and error corrections
Helpdesk tickets will no longer automatically record chatter messages when the linked Sales Order status changes. This reduces unnecessary activity in ticket conversations and keeps the discussion focused on support-related updates.
Original PR description
Before this commit: - The chatter on Helpdesk Tickets tracked and logged changes to the linked Sales Order's status. After this commit: - Explicitly set `tracking=False` on the related `sale_order_state` field in `helpdesk.ticket`. - Status updates to linked SOs will no longer automatically post tracking messages in chatter. task-6079809 Forward-Port-Of: odoo/enterprise#114078
This change hides unused stage options in Helpdesk and Project screens so users see only the settings that still apply. It also removes an unclear Helpdesk stage field from the kanban view, making the interface easier to understand.
Original PR description
We used the rotting widget in the stage field, so the stage color field is unused, as explained below in the commit- https://github.com/odoo/odoo/commit/cd9ed578803605550135cb6fd6d4c267b433abbc **Commit 2:** in helpdesk , hide Days to rot in helpdesk stage kanban view Currently, only the “Days to rot” number is displayed, so users cannot understand what the number represents. In this commit, it hide from the helpdesk stage kanban view. task-5485507
This update fixes a confusing issue for Mexican employees receiving payslips. Previously, an email was sent with an unstamped payslip before the official CFDI stamp was generated, leading to duplicate emails. Now, emails are only sent with the stamped payslip, ensuring a clearer and more accurate experience.
Original PR description
Currently, when a user confirms a payslip batch (hr.payslip.run), the base payroll module queues the PDF generation and sends an email to the employee with their payslip immediately. For Mexican payslips, this means the employee receives the email with an unstamped payslip (without CFDI UUID). Later, when the CFDI is generated, a second email is sent with the stamped version, confusing the employee. This commit prevents the email from being sent for Mexican payslips if the CFDI has not been generated yet, ensuring only the stamped payslip is emailed.
This update fixes an error in the Mexican payroll calculation, ensuring that basic salaries are accurately calculated based on full calendar periods, including unpaid leave. Previously, unpaid leave was incorrectly prorated, now the system correctly calculates the basic salary based on the full pay period, aligning with Mexican regulations.
Original PR description
In Mexico, the basic salary must be calculated based on the total calendar days of the period. This ensures that both worked days and non-working days (e.g. Sundays) contribute equally to the total…
In Mexico, the basic salary must be calculated based on the total calendar days of the period. This ensures that both worked days and non-working days (e.g. Sundays) contribute equally to the total payment. This calculation also applies to the daily schedule, as the proportional daily wage must be divided equivalently across the hours of the day. Current behavior: When an employee has an unpaid leave, the basic salary is incorrectly prorated using only the registered days/hours. Example: For a monthly wage of 30,000 MXN in a month with 22 scheduled days (21 attendances + 1 unpaid leave), the implicit daily rate becomes 1,363.63 (30,000 / 22). This leads to an incorrect basic salary of 28,636.36 MXN for the days worked. This also happens with unpaid leave for x hours, e.g., for 2 hours, the unpaid leave is calculated as 2 hours * (30,000 / (22 days * 8 hours)) = 340.90 MXN, which is incorrect. Expected behavior: The basic salary should be derived from the full period (e.g., 30 days for a month, 15 for a bi-weekly period). Example: For a 30,000 MXN wage, the daily rate should be 1,000 MXN (30,000 / 30 days). If there is 1 unpaid leave, the basic salary should be 29,000 MXN (29 days * 1,000 MXN), regardless of the number of scheduled working days in the calendar. For unpaid leaves by hours, e.g., for 2 hours, the unpaid leave should be calculated as 2 hours * (30,000 / (30 days * 8 hours)) = 250.00 MXN. To achieve this, the calculation of the days in the `_get_worked_day_lines` is: * Adjust worked days/hours for out-of-contract entries where necessary, ensuring that rest days(Sundays) are included in the count. * Get all worked hours in the lines. * Calculate the number of days to pay based on the total hours and the hours per day. ### Case: payslip does not cover the complete pay period Current behavior: If a payslip is created for a partial period, the total amount is the full period wage. Expected behavior: The total amount should be pro-rated based on the days of the period. For example, if a payslip is created for 25 days(with a monthly schedule pay), the total amount should be the daily salary multiplied by 25 days. To achieve this, `_compute_amount` is updated to calculate the wage based on the `l10n_mx_daily_salary`. Changes on tests: * Add: * `test_monthly_payslip_with_partial_leave`, `test_partial_payslip`, `test_partial_payslip_new_hire_month_31_days` and `test_partial_payslip_new_hire_month_28_days`. * `test_hourly_payslip_by_attendance` to validate when `Work Entry Source` is set to "attendance". * Update: * `test_hourly_payslip`, `test_monthly_payslip` and `test_partial_payslip_new_hire` to align with the new calculation. * Adjust payslips dates to match the `schedule_pay` in `test_regular_payslip_subsidy` and `test_weekly_schedule_pay_no_code` * Fix a one-day difference in `TestMxEdiHrPayrollCommon`(16 days instead of 15 days for a bi-weekly schedule), and update the corresponding CFDI values. * Refactor tests and add new helpers. ### Error on [warning issues generation][1] and [`_compute_is_wrong_duration`][2] The warning: `"The duration of the payslip is not accurate according to the structure type."` appears with these custom periods for Mexican Payroll, although the period is correct: * `10_days` * `14_days` * `bi-weekly` Steps to replicate: * Install `l10n_mx_hr_payroll` module. * Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company. * Go to Employees and open "Cesar Osbaldo Cruz Solorzano". * Click on "Payroll" tab, change the "Pay Schedule" to any option listed above, for example "Bi-weekly". * Go to Payroll > Payslips > Payslips and create a new pay run. * Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Bi-weekly' and the Period '01/01/2026 -> 01/15/2026'. * Click on "Continue", select Cesar and click on "Select". * It appears the warning issue. Problem: The warning is raised because of `slip.date_from + slip._get_schedule_timedelta() != slip.date_to` condition, because `_get_schedule_timedelta` function calls [`self._schedule_timedelta(schedule, self.date_from)`][3] without the `country_code` argument. In the Mexican Payroll [_schedule_timedelta is overriden][4] but it is necessary to call it with the country code to use the custom periods; similar to how the [`date_end` is computed][5]. Solution: Call `_get_schedule_timedelta` passing the `country_code` [1]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip.py#L1367 [2]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip.py#L1454 [3]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip.py#L275 [4]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/l10n_mx_hr_payroll/models/hr_payslip.py#L58 [5]: https://github.com/odoo/enterprise/blob/1666ac87b6cb40e904210fecd159df3ac5b6b33a/hr_payroll/models/hr_payslip_run.py#L211 target: 19.0 task-6073601
This update corrects a bug in the project timesheet forecasting report that incorrectly showed planned hours on public holiday days. The fix addresses an issue where the system wasn't properly accounting for general public holidays and timezone differences, ensuring accurate reporting of employee time allocation.
Original PR description
### Steps to reproduce: - Install project_timesheet_forecast module - Configure your database to have a far timezone (Montevideo/Uruguay in my case) - Create a public holiday starts from 12AM to…
### Steps to reproduce: - Install project_timesheet_forecast module - Configure your database to have a far timezone (Montevideo/Uruguay in my case) - Create a public holiday starts from 12AM to 11:59PM with a calendar - Create a planning slot for a resource that overlap with the public holiday - Check the Timesheets / Planning analysis report - Group by employees > day **- Check the date of the public holiday and notice there are still planned hours shown** - Remove the calendar from the public holidays that we created previously - Check the report once again **- Notice the day of the public holiday and the day after has no planned hours** ### Cause: In the query we are using to exclude the leave days from the report we only exclude the ones that has calendar_id assigned, not taking into consideration that some of the public holiday are general and is not applied to just one working schedule. Also if we have a leave starting midnight to 11:59PM since we store dates in database as UTC for timezone like Uruguay's one it will shift the end with one day which will introduce inconsistencies ### Fix: We check if the calendar_id is null on the resource_calendar_leaves and make sure we take timezone of the resource into account when checking the dates of the leaves. opw-5027070 Forward-Port-Of: odoo/enterprise#111846
This update prevents subscriptions from being automatically reopened after manual closure by a salesperson. Previously, approvals or payments could trigger reopening, leading to confusion and errors. This change ensures subscriptions remain closed as intended, streamlining the sales process.
Original PR description
Before this commit, when a subscription was closed manually by the salesperson, it could be reopened when a transaction was approved or an invoice paid. It could cause issue. In this case, we should not reopen automatically. task-5900481 Forward-Port-Of: odoo/enterprise#113026 Forward-Port-Of: odoo/enterprise#106487
This update resolves an issue where scanning a lot initially added an extra unit to the quantity. It also corrects a problem where packaging quantities weren't being applied to subsequent lots. The change simplifies the underlying code to ensure accurate quantity updates when using packaging with lots.
Original PR description
## Issue Currently, the Barcode app doesn't work very well when the user scans packaging and lots. If they want to apply one or multiple packagings to a specific lot, the quantity is not quite exact…
## Issue Currently, the Barcode app doesn't work very well when the user scans packaging and lots. If they want to apply one or multiple packagings to a specific lot, the quantity is not quite exact since scanning a lot already increases the quantity by 1. Also, if there is multiple lots, the packaging quantity isn't added to the last scanned lot which is problematic. ## How to reproduce 1. Active "Units of Measure & Packagings" and "Lots & Serial Numbers" settings; 2. Create a product tracked by lots with a barcode; 3. In the "Sales" tab, add a packagings (for example, "Pack of 6"); 4. Configuration > Units & Packagings > Selected the added UoM > Click on "Packaging Barcodes"; 5. Create a new barcode for the created product; 6. Create and confirm a receipt for 12 units of this product and open the operation in Barcode app; 7. Scan the product's barcode, then a lot then the packaging barcode :arrow_right: First issue: the line has 7 units. 8. Scan a second lot and scan the packaging again :arrow_right: Second issue: the packaging quantity is added to the first line, not the second one. ## Explanation About the first issue, it is the expected behavior. When the user scans a lot, we increase the line quantity by 1. When the user scans a packaging, we increase the line quantity by this packaging quantity. The issue here is the user expects to scan a lot and then to apply a packaging quantity to it. For example, scanning a lot then a pack of six should result by a line with 6 units, not 7. About the second issue, it is caused by some conditions in the `_findLine` method which don't prioritize the right line. [OPW-6045395](https://www.odoo.com/odoo/project.task/6045395)
6 changes
Resolved issues and error corrections
The Czech VIES Summary Report XML export now removes the country prefix from VAT numbers before generating the file. This brings the export in line with the official format and helps avoid validation issues when submitting the report.
Original PR description
**Steps to reproduce:** - Install the `l10n_cz_reports` module and switch to a `CZ Company` - Create an invoice for a customer with a VAT number, add a product, and set the Transaction Code (enable…
**Steps to reproduce:** - Install the `l10n_cz_reports` module and switch to a `CZ Company` - Create an invoice for a customer with a VAT number, add a product, and set the Transaction Code (enable it from the optional columns if needed). - Navigate to Reporting > VIES Summary Report. - Observe the value in the `VAT Number` column (includes country code). - From the dropdown, export the report as XML. **Observation:** In the generated XML file, the `c_vat` field contains the VAT number including the country code (e.g., `CZ12345679`) instead of only the numeric part (`12345679`). **Root cause:** At [1], the VAT number is directly taken from the report lines without removing the country code. **Fix:** This commit ensures that the `c_vat` field contains only the VAT number without the country code, complying with the official VIES XML format requirements. Ref: https://adisspr.mfcr.cz/dpr/adis/idpr_pub/epo2_info/popis_struktury_detail.faces?zkratka=DPHSHV#:~:text=Tax%20identification%20number%20of%20the%20purchaser%20(only%20the%20numeric%20part) [1]: https://github.com/odoo/enterprise/blob/c4f2c3442f30f5ac972dd136a3642acc5bcc6da2/l10n_cz_reports_2025/models/l10n_cz_vies_summary_handler.py#L29-L62 opw-6093259 Forward-Port-Of: odoo/enterprise#113083
This change fixes a problem where sales orders with discounts and foreign currencies could produce an unbalanced customer invoice and block billing. It improves invoice creation reliability for businesses using multiple currencies and discount accounts.
Original PR description
**STEP TO REPRODUCE** 1. Install the sale and accounting module. 2. Create 2 products, and setup each one with a different income account. 3. From the accounting settings, setup an account for Invoice Line discount -> Customer Invoice account. 4. Enable a currency, and create a pricelist for this currency. 5. Create the following SO: pricelist -> the pricelist you created previously. currency rate : 0.000717398539 line a: product_a, price 10, discount 57.85% line b: product_b, price 70, discount 57.85% From this SO, try to create an invoice. It will fail, saying the invoice it tried to create is unbalanced. opw-5974048
This change fixes a problem where some bank reconciliations could fail to validate after the foreign currency line was reassigned to a different account. The exchange difference is now kept correctly on the counterpart line, so the entry stays balanced and can be posted successfully.
Original PR description
Current behavior: When reconciling a bank statement line whose journal currency differs from the company currency and whose foreign_currency_id equals the company currency, mounting a vendor bill…
Current behavior: When reconciling a bank statement line whose journal currency differs from the company currency and whose foreign_currency_id equals the company currency, mounting a vendor bill with force-full-match and re-tagging the auto_balance line to a company-currency account raises UserError: "The entry is not balanced." on Validate. Expected behavior: The reconciliation should validate successfully with the exchange difference carried on the counterpart line. Required Modules - account_accountant - l10n_au (any company-currency localization reproduces, AU used here) Steps to reproduce: 1. Install account_accountant and l10n_au. Company currency = AUD. 2. Activate JPY and add a rate for 2025-10-01: 109.6788 JPY/AUD. 3. Create a bank journal: Name: ANZ EUR Account (JPY) Type: Bank Currency: JPY 4. Create an account: Code: 1082 Name: Deposits - Paid to Mazak Type: Current Assets Currency: (leave empty — accepts any) 5. Create vendor partner "Yamazaki". 6. Add a second JPY rate for 2025-11-01: 105.069 JPY/AUD (creates the FX gap between bill date and statement date). 7. Create and post a vendor bill: Vendor: Yamazaki Currency: JPY Bill date: 2025-10-01 One line: JPY 37,000,000, no tax 8. Create a bank statement line on the JPY journal: Date: 2025-11-01 Amount: -33,331,248 (JPY) Foreign currency: AUD, amount: -303,898.18 9. Open reconciliation on the statement line. 10. Manual Operations → mount the vendor bill with "Allow partial" OFF so the bill is force-matched fully. The widget now displays four lines: liquidity, new_aml (Trade Creditors), exchange_diff (Exchange Rate Loss), and auto_balance (AUD). 11. Click the auto_balance line and change its account to 1082 Deposits - Paid to Mazak. 12. Click Validate. Expected result The move posts: ANZ -303,898.18 / Trade Creditors +352,149.54 / Deposits -48,251.36, Σ = 0. Actual result UserError: The entry is not balanced. Cause of the issue: In _lines_prepare_auto_balance_line (bank_rec_widget.py:424-475), the auto_balance line's amount_currency is computed from the JPY gap converted at the transaction rate while its balance is computed independently as the company-currency plug. When the statement line's foreign_currency_id equals the company currency, currency_id on the auto_balance line resolves to the company currency, yet the two numbers disagree. account.move.line._inverse_amount_currency (account_move_line.py:1250-1260) enforces balance = amount_currency whenever currency_id == company_currency_id, so at move.write the balance is silently clamped to amount_currency, dropping the FX component. _validation_lines_vals (bank_rec_widget.py:1382-1406) has already squashed the exchange_diff into the new_aml, so the FX stays on the JPY side while its AUD-side offset is clamped away. _check_balanced (account_move.py:2462-2474) then raises. Fix: In _lines_prepare_auto_balance_line, when transaction_currency_id == company_currency_id, force amount_currency = open_balance before returning the vals. The line then reaches account.move.write already satisfying the _inverse_amount_currency invariant, the clamp is a no-op, and the FX squashed into new_aml is preserved. opw-6122823
This update resolves a reporting discrepancy where planned hours were incorrectly shown for public holidays. The fix accurately accounts for public holidays applied across multiple schedules and handles timezone differences, ensuring accurate timesheet forecasts.
Original PR description
### Steps to reproduce: - Install project_timesheet_forecast module - Configure your database to have a far timezone (Montevideo/Uruguay in my case) - Create a public holiday starts from 12AM to…
### Steps to reproduce: - Install project_timesheet_forecast module - Configure your database to have a far timezone (Montevideo/Uruguay in my case) - Create a public holiday starts from 12AM to 11:59PM with a calendar - Create a planning slot for a resource that overlap with the public holiday - Check the Timesheets / Planning analysis report - Group by employees > day **- Check the date of the public holiday and notice there are still planned hours shown** - Remove the calendar from the public holidays that we created previously - Check the report once again **- Notice the day of the public holiday and the day after has no planned hours** ### Cause: In the query we are using to exclude the leave days from the report we only exclude the ones that has calendar_id assigned, not taking into consideration that some of the public holiday are general and is not applied to just one working schedule. Also if we have a leave starting midnight to 11:59PM since we store dates in database as UTC for timezone like Uruguay's one it will shift the end with one day which will introduce inconsistencies ### Fix: We check if the calendar_id is null on the resource_calendar_leaves and make sure we take timezone of the resource into account when checking the dates of the leaves. opw-5027070 Forward-Port-Of: odoo/enterprise#111846
This update corrects a technical issue in the French localization of Odoo. A tax tag ('17') was incorrectly applied to service taxes, specifically the '8.5% EU Service' tax. This change ensures that tax tags are accurately assigned to goods and services, aligning with French tax regulations.
Original PR description
**Issue:** In French localization, a tax tag (i.e. "17") was wrongly added on "8.5% EU Service" tax. This tax tag should only be applied on taxes for goods, not service. opw-5871998 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260641
This update resolves an issue where sending final invoices to ZATCA would fail when down-payments had been reversed. The fix ensures that reversed down-payment invoices are correctly handled, preventing a 'singleton' error and allowing the final invoice to be successfully generated. This improves the reliability of ZATCA invoice processing.
Original PR description
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1.…
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1. Configure a SA company and setup ZATCA 2. Create a sale order and confirm it 3. Deliver the product line. 3. From the sale order, create a down-payment invoice (fixed amount, e.g. 115) and post it (DP1). 4. On DP1, click "Credit Note" and choose "Full refund and new draft invoice"; validate. DP1 becomes `reversed` and a new draft down-payment DP2 is created. Post DP2. 5. From the sale order, create the final regular invoice and post it. 6. Send the final invoice to ZATCA (or generate its XML) -> `ValueError: Expected singleton: account.move(a, b)`. Root cause: _l10n_sa_get_line_prepayment_vals looks up the related down-payment move through the down-payment sale order line shared with the product line. The filter matched any out_invoice with _is_downpayment() == True, so the reversed DP1 and the active DP2 both ended up in the recordset, and reading .name raised the singleton error. Prefer non-reversed down-payment moves when available, but fall back to reversed ones if no alternative exists (e.g. when generating a credit note of the final invoice after the original down-payment was itself reversed). opw-6116265 Forward-Port-Of: odoo/odoo#259384
1 change
Resolved issues and error corrections
This update keeps Odoo working correctly on Python 3.14 and the latest Ubuntu release by adjusting internal code and package requirements. It also fixes a mailing-related error so background checks and tests continue to run reliably on the newer Python version.