Daily updates from Odoo
Navigate
Branch
Friday, July 3, 2026
350 changes
11 changes
Resolved issues and error corrections
When warehouse staff use the barcode app and click “put in pack,” Odoo now shows the package type selection prompt when the delivery settings require it. This prevents users from missing required packaging details and keeps barcode workflows aligned with standard delivery operations.
Original PR description
### Steps to reproduce: - In the settings enable: Packages - On the operation type `Delivery Order` set "Set Package Type" - Create and confirm a delivery for 1 unit of a product P + reserve it - Got…
### Steps to reproduce: - In the settings enable: Packages - On the operation type `Delivery Order` set "Set Package Type" - Create and confirm a delivery for 1 unit of a product P + reserve it - Got to the barcode app to process the delivery - Scan your product and click "put in pack" #### > The put in pack wizard allowing you to set a package type on the new package does not pop up. ### Cause of the issue: As a general rule of thumb the wizard is suppose to be displayed when the option is enabled and when a package/package type is not already provided to the call: https://github.com/odoo/odoo/blob/5dbc448d336c7ff22803ae91d5014eb6d0a07234/addons/stock/models/stock_package.py#L332-L341 https://github.com/odoo/odoo/blob/5dbc448d336c7ff22803ae91d5014eb6d0a07234/addons/stock/models/stock_move_line.py#L1236-L1238 However an override was added to the barcode module so that the wizard is never displayed when the action is launched from the barcode app: https://github.com/odoo/enterprise/blob/673d449f38cd3eff27c44270c8f7edf91d0ecd02/stock_barcode/models/stock_move_line.py#L193-L196 The idea behind this override was that you could provide the package type id via scans and hence that is was not necessary. However, if you click directly on the put in pack button, the wizard still make sense and should therefore be displayed under the same conditions. opw-6325092 Forward-Port-Of: odoo/enterprise#122308
This update corrects a bug where loyalty reward descriptions weren't consistently translating across multiple languages. Previously, changes to a discount's description only updated the current language, leaving other languages unchanged. Now, all languages will reflect the updated description, ensuring accurate and consistent messaging for customers.
Original PR description
### Steps to Reproduce 1. Activate any other language (ex. FR) 2. Create a new Discount code in Discount & Loyalty 3. Change your user language preference to FR, open the newly created loyalty…
### Steps to Reproduce 1. Activate any other language (ex. FR) 2. Create a new Discount code in Discount & Loyalty 3. Change your user language preference to FR, open the newly created loyalty reward, and change the Description on Order to Test Discount for both languages 4. Navigate to the backend Product Variants menu and observe how its name did not translate in English ### Description of the issue/feature this PR addresses: **Issue:** When you edit a translation for a loyalty.reward description in a multi-language setup, the product name (`discount_line_product_id.name`) fails to receive the complete translation in all languages. It only updates the current language. **Solution:** Override the 'update_field_translations' method on the loyalty.reward model. When changes are saved for the 'description' field on the discount code, intercept the payload and mirror directly at the discount product's `name` field. ### Current behavior before PR: Updating the reward description only updates the current language and all other languages do not change. ### Desired behavior after PR is merged: For all languages in which changes are made in a discount code's description, the discount line product name will reflect the same changes. opw-6314760 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273821 Forward-Port-Of: odoo/odoo#271680
This update ensures the website always displays the default cookie policy page when the cookies bar is enabled and the policy field is cleared. Previously, clearing the policy field without disabling the cookies bar resulted in the page disappearing, requiring a workaround. This fix maintains a consistent and compliant user experience.
Original PR description
Steps to reproduce: - enable the cookies bar in the website settings and save - clear the "Cookie Policy Page" field and save The website was left without a cookie policy page while the cookies bar was still enabled. Since the settings view only displays the field when it has a value, it disappeared with no way to set it back, other than toggling the cookies bar off and on again. The default policy page was only restored when the `cookies_bar` flag itself changed, so a write clearing only `cookie_policy_id` slipped through. Restore the default page whenever the policy is emptied while the cookies bar remains enabled, so the field reappears with the default page after saving. task-6356766
This update ensures that only complete and accurate buyer address data is sent to Fiskaly, our payment processing partner. Previously, placeholder values like 'N/A' were included, which is now corrected to only send available information, streamlining the process and improving data quality. This change avoids unnecessary data transmission and potential issues with Fiskaly.
Original PR description
In this commit: ------------------- - Buyer address fields are optional and should only be sent to Fiskaly when they are actually available. - Avoid sending placeholder values like "N/A". If the data is not present, the fields should simply be omitted from the request. task: 6113133 Forward-Port-Of: odoo/enterprise#122188 Forward-Port-Of: odoo/enterprise#113621
This update ensures the website correctly displays the cookie policy page even after it's cleared through the settings. Previously, clearing the field only worked when the cookies bar was toggled off and on, creating a confusing user experience. This fix guarantees the policy page is always visible when the cookies bar is enabled.
Original PR description
Steps to reproduce: - enable the cookies bar in the website settings and save - clear the "Cookie Policy Page" field and save The website was left without a cookie policy page while the cookies bar was still enabled. Since the settings view only displays the field when it has a value, it disappeared with no way to set it back, other than toggling the cookies bar off and on again. The default policy page was only restored when the `cookies_bar` flag itself changed, so a write clearing only `cookie_policy_id` slipped through. Restore the default page whenever the policy is emptied while the cookies bar remains enabled, so the field reappears with the default page after saving. task-6356766
This update resolves an issue where the Odoo logging system was not correctly configured in version 19.4. Specifically, a necessary argument was missing from a key function, ensuring accurate logging data capture. This ensures consistent and reliable logging performance.
Original PR description
During the forwardport, it was missed that get_log_metadata needs an argument starting from 19.0. Forward-Port-Of: odoo/odoo#273694
A recent change in Cloudflare functionality disrupted how turnstile callbacks were handled in the website module. To ensure turnstile functionality continues to work correctly, the team reverted to a previous implementation that doesn't rely on specific external widget details. This resolves a technical issue impacting turnstile performance.
Original PR description
Callbacks were changed to use a single shared callback instead of a bunch of callbacks that captured a specific container. Cloudlfare since introduced a change that breaks this change by not making "this" available inside callbacks. We thus go back to the previous implementation that did not rely on implementation details of the external widget. related: 5aa5cf62a9d3f2b0c862b0aab337b22367843fa6 Forward-Port-Of: odoo/odoo#273538 Forward-Port-Of: odoo/odoo#273336
This update fixes an issue where customer addresses were excessively long in form view titles and breadcrumbs, making them difficult to read. The change ensures only the customer's name is displayed, aligning with how other fields are formatted, resulting in a cleaner and more user-friendly navigation experience.
Original PR description
- Create a new Invoice; - Assign a Customer with a multiline address; - Click on the internal link (arrow icon) of the Customer field. Before this commit, the form view title and the breadcrumb would contain not only the customer's name but also their full address. This resulted in an excessively large and unreadable breadcrumb. Now, only the name is retained. This commit applies the same behavior already used in many2one fields: the display name is split by line breaks, and only the first line is kept for the title and breadcrumb. task-id 6329662 Forward-Port-Of: odoo/odoo#272550 Forward-Port-Of: odoo/odoo#272059
This update resolves an issue where self-ordering table references were being lost when a self-order was created from a QR code. The fix ensures that the original table link is maintained, allowing users to seamlessly validate and pay their orders, even when the table is initially empty. This improves the reliability of the self-ordering mobile experience.
Original PR description
Steps to reproduce: --------------- - Enable QR Menu & Ordering in POS - Enable Service at Table - Create a self-order from a table QR - Validate/pay the order from the POS Cause: ----------- The write override unconditionally `table_id` to `self_ordering_table_id`, even when `table_id` was falsy, clearing the original self-order table link. Fix: ---------- Only update `self_ordering_table_id` when `table_id` is explicitly set and truthy. Task-6272642 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268459
This update fixes a minor issue with the website event quiz where users weren't receiving a clear confirmation message after completing a quiz. The change ensures a positive and informative message is displayed, enhancing the user experience. This improves the overall impression of the event tracking feature.
Original PR description
opw-6332274 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#272593 Forward-Port-Of: odoo/odoo#272371
This update corrects a calculation error in the Swiss tax report (l10n_ch). Previously, negative values in certain report lines resulted in incorrect subtractions. The fix ensures that these lines display positive values, guaranteeing accurate tax report totals. This improves the reliability of financial reporting for Swiss clients.
Original PR description
### Issue: In 19.0, the values of lines 415 and 420 in the Swiss tax report are negative, causing line 479 to add them instead of subtracting Line 479 formula: `tax_ch_400 + tax_ch_405 + tax_ch_410 -…
### Issue: In 19.0, the values of lines 415 and 420 in the Swiss tax report are negative, causing line 479 to add them instead of subtracting Line 479 formula: `tax_ch_400 + tax_ch_405 + tax_ch_410 - tax_ch_415 - tax_ch_420` For the subtraction to be correct, 415 and 420 must be positive ### Cause: In 18.0, each tax grid had two variants (`+415`/`-415`) allowing the user to control the sign manually The double negative (`-*-`) incidentally produced positive values in the report In 19.0, the unified tax grid merges them into a single tax grid (`415`) with automatic sign handling 415 and 420 are correction lines that must appear positive in the report so that 479 subtracts them correctly The formulas were not updated to reflect this change ### Steps to reproduce: - Install `l10n_ch_reports` and `accountant` - Switch to `CH Company` - Create and confirm a Bill (Amount: 100, Tax: 8.1%) - Create and post a Journal Entry: - Account: 1170 Input Tax (VAT), Credit: 2, Tax Grids: 415 and 420 - Account: 1021 Bank, Debit: 2 - Open the Tax Report for this month Before the fix, lines 415 and 420 are negative and line 479 adds them instead of subtracting opw-6311126 Forward-Port-Of: odoo/odoo#272385
21 changes
New functionality added to Odoo
This update adds missing translations for various messages within the Point of Sale (POS) modules. This ensures that the POS system is accessible and understandable for users in different languages, improving the overall user experience and supporting global operations. The changes include translations for dialogs, errors, and UI messages across multiple POS-related applications.
Original PR description
pos* = All POS module In this commit: -------------------------------- Add missing translations for user-visible strings across POS modules. - Translated dialogs, errors, alerts, and other UI-visible messages - Updated Python-side UserError, ValidationError, and warning messages Task-5406947 Related PR-https://github.com/odoo/enterprise/pull/102094 Forward-Port-Of: odoo/odoo#273265 Forward-Port-Of: odoo/odoo#239972
This update adds missing translations for various user-visible messages within the Odoo POS modules. This ensures that the POS system is correctly localized for users in different languages, improving the overall user experience and supporting international expansion. It addresses inconsistencies in translated text across multiple POS applications.
Original PR description
pos* = All POS module In this commit: -------------------------------- Add missing translations for user-visible strings across POS modules. - Translated dialogs, errors, alerts, and other UI-visible messages - Updated Python-side UserError, ValidationError, and warning messages Task-5406947 Related PR-https://github.com/odoo/odoo/pull/239972 Forward-Port-Of: odoo/enterprise#122403 Forward-Port-Of: odoo/enterprise#102094
Enhancements to existing features
The timesheet timer now opens with a likely project already selected based on the employee's recent timesheets, while still prioritizing the project or task currently being viewed. It also avoids preselecting archived or template records, reducing manual selection and preventing invalid time entries.
Original PR description
When opening the timesheet systray, the timer is now prefilled with the project to which the employee's three most recent timesheets are all linked, since they are most likely to keep logging time on it. The currently viewed project or task takes precedence over the favorite project, and viewing a project form now prefills the timer as well, just like task views already do. task-6290859 Forward-Port-Of: odoo/enterprise#120028
This update enhances the expense dashboard by ensuring managers can accurately view the total expenses of their team members. Previously, the dashboard's filters didn't align with the status of expenses ('To Submit', 'Waiting Approval', 'Waiting Reimbursement'). Now, managers will see consolidated expense totals, providing better visibility and control.
Original PR description
For the expense dashboard with the states 'To Submit', 'Waiting Approval' and 'Waiting Reimbursement', make these states compliants with the current filters of the list view. It means, for example, that a manager can see the total amounts of the people he manages. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273398 Forward-Port-Of: odoo/odoo#270234
This update streamlines logging within the IoT drivers by removing unnecessary stack traces, reducing log clutter when checking ports other than FDM. The change also refines error handling for improved efficiency and stability. This improves the overall reliability of the IoT integration.
Original PR description
We remove the stack trace from the exception reading FDM response to avoid polluting the logs when probing non FDM ports. We also now catch a more precise `IndexError` instead of `Exception` as it wasn't necessary to catch this wide. We also caught the opportunity to ruff the file. Forward-Port-Of: odoo/odoo#272078
Resolved issues and error corrections
Audit reports exported to PDF now include images that users inserted with the file command. This prevents missing visual evidence or context in downloaded reports and makes the PDF match the report content more accurately.
Original PR description
Currently, when a user uses the `/file` command to insert an image into an audit report and exports the report to PDF, the image is omitted from the generated PDF. To improve the support of those blocks, we will pre-process the document and replace the embedded files that correspond to images with standard image elements before PDF generation. This will ensure that images are correctly rendered and displayed within the document's text flow in the exported PDF. Task [link](https://www.odoo.com/odoo/project.task/5115280) task-5115280 Forward-Port-Of: odoo/enterprise#122699 Forward-Port-Of: odoo/enterprise#121673
This update fixes a bug where loyalty reward descriptions weren't consistently translating across multiple languages. Now, when you change the description of a discount code in one language, it automatically updates in all other languages, ensuring accurate and localized messaging for our customers. This improves the overall user experience and consistency of our loyalty program.
Original PR description
### Steps to Reproduce 1. Activate any other language (ex. FR) 2. Create a new Discount code in Discount & Loyalty 3. Change your user language preference to FR, open the newly created loyalty…
### Steps to Reproduce 1. Activate any other language (ex. FR) 2. Create a new Discount code in Discount & Loyalty 3. Change your user language preference to FR, open the newly created loyalty reward, and change the Description on Order to Test Discount for both languages 4. Navigate to the backend Product Variants menu and observe how its name did not translate in English ### Description of the issue/feature this PR addresses: **Issue:** When you edit a translation for a loyalty.reward description in a multi-language setup, the product name (`discount_line_product_id.name`) fails to receive the complete translation in all languages. It only updates the current language. **Solution:** Override the 'update_field_translations' method on the loyalty.reward model. When changes are saved for the 'description' field on the discount code, intercept the payload and mirror directly at the discount product's `name` field. ### Current behavior before PR: Updating the reward description only updates the current language and all other languages do not change. ### Desired behavior after PR is merged: For all languages in which changes are made in a discount code's description, the discount line product name will reflect the same changes. opw-6314760 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271680
This update resolves an error that occurred when previewing canceled subscription orders. The fix ensures that canceled orders use the standard sale order preview instead of attempting to render the subscription-specific portal view, preventing a technical error. This improves the user experience for canceled subscriptions.
Original PR description
Currently, an error occurs when a user previews a canceled subscription order. **Steps to Reproduce:** - Install `sale_subscription` module. - Go to `Subscriptions` and create a `subscription order`…
Currently, an error occurs when a user previews a canceled subscription order.
**Steps to Reproduce:**
- Install `sale_subscription` module.
- Go to `Subscriptions` and create a `subscription order` with:
- a `subscription product`,
- a `recurring plan`,
- an `Until` (end date) value.
- `Cancel` the subscription order.
- Click `Preview`.
`TypeError: unsupported operand type(s) for +: 'bool' and 'relativedelta'`
When previewing a subscription order, the portal view is rendered. During rendering, the
subscription portal template is used, which computes tax values and requires calculating the
next invoice date based on the recurring plan's billing period. However, for canceled
subscription orders, next_invoice_date is False because it is only set when the order is in
the sale state. As a result, an error is raised [2].
This commit ensures that only subscription orders in the sale state use the subscription
portal template. Canceled subscription orders use the default sale order preview, similar
to orders in the draft and sent states. This is appropriate because canceled subscriptions
are not correctly displayed in the subscription portal, and they should not attempt to
render the subscription-specific portal view.
[1]- https://github.com/odoo/enterprise/blob/f833154b61fdb73c24d99462815a55313212b909/sale_subscription/controllers/portal.py#L686-L687
[2]- https://github.com/odoo/enterprise/blob/f833154b61fdb73c24d99462815a55313212b909/sale_subscription/models/sale_order.py#L2172-L2175
sentry-7579114635This update corrects a bug in the self-ordering POS feature. Previously, when a self-order was created, the link to the original table QR code was lost, causing issues with order validation and payment. The fix ensures that the table reference is maintained correctly, allowing users to seamlessly validate and pay their self-ordered items.
Original PR description
Steps to reproduce: --------------- - Enable QR Menu & Ordering in POS - Enable Service at Table - Create a self-order from a table QR - Validate/pay the order from the POS Cause: ----------- The write override unconditionally `table_id` to `self_ordering_table_id`, even when `table_id` was falsy, clearing the original self-order table link. Fix: ---------- Only update `self_ordering_table_id` when `table_id` is explicitly set and truthy. Task-6272642 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268459
This update fixes an issue where customer form view titles and breadcrumbs displayed excessively long addresses. Now, only the customer's name is shown, creating a cleaner and more readable navigation experience. This change aligns with existing behavior in other Odoo fields.
Original PR description
- Create a new Invoice; - Assign a Customer with a multiline address; - Click on the internal link (arrow icon) of the Customer field. Before this commit, the form view title and the breadcrumb would contain not only the customer's name but also their full address. This resulted in an excessively large and unreadable breadcrumb. Now, only the name is retained. This commit applies the same behavior already used in many2one fields: the display name is split by line breaks, and only the first line is kept for the title and breadcrumb. task-id 6329662 Forward-Port-Of: odoo/odoo#272550 Forward-Port-Of: odoo/odoo#272059
This update corrects a bug where global discounts were incorrectly applied in Point of Sale for users with Dutch (or similar) localization settings. The fix ensures that discount percentages, formatted with a comma as the decimal separator, are correctly calculated and applied, preventing unintended full discounts.
Original PR description
When using Dutch (or similar locales where the decimal separator is a comma), a configured global discount percentage with decimals is misapplied in POS. For example, a default discount of 8,33% is…
When using Dutch (or similar locales where the decimal separator is a comma), a configured global discount percentage with decimals is misapplied in POS. For example, a default discount of 8,33% is shown in the discount popup as 8.33% and, when confirmed without editing, applies a 100% discount on the order instead of 8,33%. Steps to reproduce: ------------------- * Activate Belgian localization for accounting * Set the user language to Dutch (Netherlands) or Dutch (Belgium) * In Point of Sale settings, enable global discounts and set the default discount percentage to 8,33% * Open a POS session, add a product to the cart, and click Discount * Confirm the popup without changing the value > Observation: The popup displays 8.33% (with a dot). After confirmation, the order receives a full discount instead of 8,33%. Why the fix: ------------ The discount popup initialized its value with `String(discount_pc)`, which always uses a dot as decimal separator. POS then parses the input with locale-aware rules where `.` is the thousands separator, so "8.33" is read as 833 and capped to 100%. Format the default discount percentage with `formatFloat` so the popup starts with the correct localized value (e.g. "8,33"). opw-6334367 Forward-Port-Of: odoo/odoo#273022
This update resolves an issue where the webhook URL field in the Odoo form view would overflow, preventing users from clicking the renew button. The fix ensures the URL is properly truncated, maintaining the button's accessibility and functionality. This improves the user experience for renewing subscriptions.
Original PR description
Before this commit, the webhook URL field could overflow in the form view, causing the adjacent renew button to become partially or fully unclickable. This commit fixes the issue by allowing the copy clipboard URL field container to shrink properly within layout, so the URL is truncated as intended and the renew button remains accessible. task:6317827 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a minor issue with the website event quiz where users weren't receiving a clear success message after completing a quiz. The change ensures a positive and informative message is displayed, enhancing the user experience. This improves the overall usability of the event tracking feature.
Original PR description
opw-6332274 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#272593 Forward-Port-Of: odoo/odoo#272371
This update resolves issues where emojis inserted from the suggestion list didn't correctly remove the previous search text and caused cursor placement problems after emoji replacement on mobile devices. The changes ensure emojis are inserted properly and cursor positioning is accurate, improving the user experience.
Original PR description
**Issue 1:** Step to reproduce: - Type ':wave' to open suggestion list - Now click on any emoji from the suggestion list Description of the issue: - The selected emoji gets inserted, but the…
**Issue 1:** Step to reproduce: - Type ':wave' to open suggestion list - Now click on any emoji from the suggestion list Description of the issue: - The selected emoji gets inserted, but the `searchNode` `:wave` does not get removed and remains beside the inserted emoji Cause: - When the user clicks an emoji from the suggestion list, focus shifts to the suggestion list item. As a result, `selection.extend()` is unable to properly select the searchNode in the editable area. Because the `searchNode` is not selected, `deleteSelection()` fails to remove it before inserting the emoji. Solution: - Added the `user-select-none` class to the suggestion list to prevent selection/focus shift on emoji click, ensuring the searchNode is properly selected and replaced by the selected emoji **Issue 2:** Steps to reproduce: - Open a To-do on a mobile device. - Type `:p` to create an emoji. - Press Backspace. Issue: - When using the SwiftKey keyboard, pressing Backspace after an emoji can result in an incorrect cursor position. Cause: - When Backspace is pressed, a selection snapshot is cached during the `keydown` event. - Later, `deleteBackward` converts the emoji back to its corresponding expression (:p) by triggering an undo operation, but the cached selection does not get updated. As a result, the previously cached selection is reused, causing the cursor to be placed incorrectly. Solution: - After performing the undo, update the cached selection to match the new cursor position. - This ensures that the latest selection is used instead of the outdated selection captured during `keydown`. **Issue 3:** Steps to reproduce: - Open a To-do on a mobile device. - Type `:p` to create an emoji. - Press Backspace. Issue: - Pressing Backspace on an emoji does not revert it to its matching expression (`:p`). Cause: - On mobile devices, `event.key` can be undefined in keydown. As a result, `deleteBackward` is triggered through the `beforeinput` event, which correctly reverts the emoji to its matching expression. However, after that, the `input` event is triggered and converts the expression back into the emoji again, making it appear as if the emoji was not reverted. Solution: - When the event type is `deleteContentBackward`, skip converting the expression back into an emoji and return early. task-6201173 Forward-Port-Of: odoo/odoo#263777
This update corrects a calculation error in the Swiss tax report (l10n_ch). Previously, negative values in specific report lines resulted in incorrect subtractions. The fix ensures these lines display positive values, guaranteeing accurate tax report totals. This improves the reliability of Swiss tax reporting within the Odoo system.
Original PR description
### Issue: In 19.0, the values of lines 415 and 420 in the Swiss tax report are negative, causing line 479 to add them instead of subtracting Line 479 formula: `tax_ch_400 + tax_ch_405 + tax_ch_410 -…
### Issue: In 19.0, the values of lines 415 and 420 in the Swiss tax report are negative, causing line 479 to add them instead of subtracting Line 479 formula: `tax_ch_400 + tax_ch_405 + tax_ch_410 - tax_ch_415 - tax_ch_420` For the subtraction to be correct, 415 and 420 must be positive ### Cause: In 18.0, each tax grid had two variants (`+415`/`-415`) allowing the user to control the sign manually The double negative (`-*-`) incidentally produced positive values in the report In 19.0, the unified tax grid merges them into a single tax grid (`415`) with automatic sign handling 415 and 420 are correction lines that must appear positive in the report so that 479 subtracts them correctly The formulas were not updated to reflect this change ### Steps to reproduce: - Install `l10n_ch_reports` and `accountant` - Switch to `CH Company` - Create and confirm a Bill (Amount: 100, Tax: 8.1%) - Create and post a Journal Entry: - Account: 1170 Input Tax (VAT), Credit: 2, Tax Grids: 415 and 420 - Account: 1021 Bank, Debit: 2 - Open the Tax Report for this month Before the fix, lines 415 and 420 are negative and line 479 adds them instead of subtracting opw-6311126 Forward-Port-Of: odoo/odoo#272385
This update corrects a bug in gift card redemption within Point of Sale (PoS). When the default tax setting was 'tax included,' the system incorrectly deducted the full gift card value. The fix ensures accurate tax calculations and consistent totals, preventing under-deduction and maintaining correct tax line displays.
Original PR description
We had a bug when redeeming a gift card when the default taxe of the company was tax_included. Steps to reproduce: ------------------- * Set default 15% tax to bo Tax Included * In PoS, sell a gift card * Use that gift card in a new order > Observation: Deducted amount is 43.48, that's 50 without taxes Why the fix: ------------ We now compute the gift card reward line from a tax-aware amount and choose the unit price based on whether the discount product’s tax is price-included, ensuring we deduct the full intended value while displaying the correct tax. This prevents under-deduction (untaxed base only) and avoids re-adding tax on top, keeping totals and tax lines consistent. opw-5441106 Forward-Port-Of: odoo/odoo#244735
This update resolves an issue where the preview of webhook sample payloads would fail when certain fields returned complex data structures (specifically `frozendict` objects). The fix ensures that the payload is correctly formatted for JSON serialization, preventing the preview from crashing and allowing users to properly configure webhook notifications.
Original PR description
**Steps to Reproduce:** - Create a Server Action of type 'Webhook Notification'. - Select a model containing a field that returns a `frozendict`-based structure (e.g. `account.move` →…
**Steps to Reproduce:** - Create a Server Action of type 'Webhook Notification'. - Select a model containing a field that returns a `frozendict`-based structure (e.g. `account.move` → `needed_terms`). - Add the field to the webhook fields. - Open the webhook sample payload preview. **Issue:** - During sample payload generation: - The selected fields are read from a sample record. - A selected field returns a structure containing `frozendict` objects. - The payload is serialized using `json.dumps()`. - JSON serialization fails with: ```text TypeError: keys must be str, int, float, bool or None, not frozendict ``` - The webhook sample payload computation crashes and the preview cannot be displayed. **Root Cause:** - The webhook sample payload may contain `frozendict` objects returned by selected fields. - The serializer used for payload generation does not handle such mapping-like objects, causing `json.dumps()` to fail. **Solution:** - Use a serializer that converts mapping-like objects into JSON-compatible structures before serializing the webhook sample payload. **OPW-6295777** 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#272324 Forward-Port-Of: odoo/odoo#271864
This update allows users to define default values for specific fields within Odoo, but only for fields they are authorized to access. This ensures data consistency and simplifies workflows by allowing users to pre-populate fields with their appropriate settings. It addresses a previous limitation where default values were not always correctly applied based on user permissions.
Original PR description
Users should be able to set default values only for fields they have access to. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273619 Forward-Port-Of: odoo/odoo#273089
This update fixes an issue where incoterm information was missing from purchase quotation reports. After a recent code update, the report now correctly displays the incoterm, providing clearer visibility for sales and procurement teams. This ensures accurate reporting and better decision-making regarding international shipments.
Original PR description
After a refactor the incoterm and location didn't show on the purchase quotation Task-id: 6206523 Forward-Port-Of: odoo/odoo#270991
This update resolves an issue preventing users from creating rental orders. The fix grants necessary access to rental picking users, allowing them to successfully create and manage rental orders. This ensures a smoother experience for users utilizing the rental order functionality.
Original PR description
Issue: --- It's not possible to create rental orders without stock.lot access. Steps to reproduce: 1- Change demo user access: - All inventory accesses: No 2- Enable `Rental Transfers`. 3- Login Demo user. 4- Create a rental order. You will get access error. Cause and Fix: --- `stock.lot` model is in only accessed by `group_stock_user`. As a result fields such as `reserved_lot_ids` will be problematic when we don't have stock access. We initially tried to fix the issue by limiting the problematic fields to group stock user. However that limits the user from rental pickup. Instead we are giving the required access to group rental picking user. opw-6281154 Forward-Port-Of: odoo/enterprise#120670
This update fixes an issue where bank reconciliation calculations were inaccurate when dealing with foreign currencies. The system now correctly converts amounts from the journal currency to the company currency, ensuring accurate balance calculations and preventing errors during reconciliation processes. This improves the reliability of financial reporting.
Original PR description
### Issue: When a bank journal uses a foreign currency, reconciliation model lines with `Amount Type: From Label` (regex) could raise a constraint error or produce incorrect balances on the journal…
### Issue: When a bank journal uses a foreign currency, reconciliation model lines with `Amount Type: From Label` (regex) could raise a constraint error or produce incorrect balances on the journal entry ### Cause: The `balance` of the generated move line was set to the raw value extracted by the regex, without converting it from the journal currency to the company currency This violated the sign constraint between `balance` and `amount_currency` when the exchange rate caused a mismatch, raising a `_check_amount_currency_balance_sign` error The `amount_currency` was already correctly set Only the `balance` conversion was missing ### Steps to reproduce: - Install `accountant` - Enable a foreign currency (e.g. EUR) with two rates: yesterday: ratio < 1 (e.g. 0.5), today: ratio > 1 (e.g. 2.0) - Create a Bank journal in EUR - Open Bank Reconciliation for that journal - Add two transactions (one dated yesterday, one today) (Ref: "test BANK:0001690,00EUR EXP:00033,80", amount: 1656.20) - Create a reconciliation model (3 dots > Manage Models) (name: From Label): -- Account: 101401 Bank, Amount: BANK:0*(\d+),(\d+) -- Account: 600000 Expenses, Amount: EXP:0*(\d+),(\d+) - Apply the model on both transactions Before the fix, one raised an error due to the constraint violation - From the list view, open the Journal Entry for the other transaction Before the fix, `balance` was not converted to company currency opw-6292839 Forward-Port-Of: odoo/enterprise#121114
12 changes
Resolved issues and error corrections
The Work Order employee planning view now only loads employees for the active company. This prevents access errors in multi-company setups and lets manufacturing planners open the schedule reliably.
Original PR description
Issue ----- When there are employees in different companies, opening the Work Order planning view causes an access error. Steps to reproduce ----- - Create 2 companies - Create an employee in each company - Go to Manufacturing > Planning > Employee Planning > Acces error Cause ----- The error happens in `_gantt_unavailability` when trying to browse the employee list https://github.com/odoo/enterprise/blob/5ddef3263d4d9788b894ea465fb183e53d4c9e89/mrp_workorder/models/mrp_workorder.py#L696 This function is called by `get_gantt_view` when loading the page. The list of ids come from https://github.com/odoo/enterprise/blob/5ddef3263d4d9788b894ea465fb183e53d4c9e89/mrp_workorder/models/mrp_workorder.py#L639 We can provide a domain to restrict the search to the current company instead. ----- Ticket: opw-6302105
This update fixes a bug where employees with the 'Judicially Separated' marital status were incorrectly receiving zero tax deductions. The update now accurately calculates withholding taxes and special social contributions for this status, ensuring accurate payroll processing. This resolves a potential overpayment of taxes.
Original PR description
**Steps to Reproduce:** 1. Create a new employee. 2. Set their marital status to "Judicially Separated". 3. Generate a payslip. **Reason:** - The "Judicially Separated" marital status was not explicitly included in the conditions for calculating withholding taxes or special social contributions. As a result, employees with this status bypassed the calculations entirely, receiving a rate of 0 for both and a significantly larger reduction on master which also appears to be incorrect. **Solution:** - Included the 'separated' status in isolated tax and CSSS logic. Task-6321245 Forward-Port-Of: odoo/enterprise#122193 Forward-Port-Of: odoo/enterprise#121457
This update resolves an issue where the video preview stopped working after the first scan in the Brave browser. The fix automatically restarts the video playback after a pause, ensuring the barcode scanning functionality continues to work correctly.
Original PR description
Issue: ====== - In the latest Brave Browser version (1.90+), the first scan works properly, but the video preview disappears during the second scan. Fix: ==== - During the second scan, the video is unexpectedly paused. We now automatically play the video again if it is paused. task-6218047 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265436
This update ensures that short URLs generated by the Email Marketing module consistently use the correct base URL (`web.base.url`) regardless of the context. Previously, these URLs were incorrectly using company-specific domains, leading to unexpected behavior in automated processes like mass mailing queues. This fix corrects a critical issue that impacts URL accuracy across all operations.
Original PR description
The [`_compute_short_url_host`](https://github.com/odoo/odoo/blob/a81fa8699c89385d2cccb260ada07255c6ea1275/addons/website_links/models/link_tracker.py#L20-L24) override builds link.tracker short URLs…
The [`_compute_short_url_host`](https://github.com/odoo/odoo/blob/a81fa8699c89385d2cccb260ada07255c6ea1275/addons/website_links/models/link_tracker.py#L20-L24) override builds link.tracker short URLs from `website.get_current_website()` and the current company's website domain. It was introduced by https://github.com/odoo/odoo/commit/f13ecb15af7f0bdc67e37dfb41e8bac77f5a541a for a multi-company backend flow (users switching companies to post social marketing links), but it runs for every compute, including CRON contexts with no HTTP request such as the mass-mailing queue. Without a request, `get_current_website()` picks an arbitrary website (the first in the database) and `self.env.company` resolves to the user's main company, so the short URL uses that company's website domain instead of `web.base.url`. Fall back to `super()._compute_short_url_host()` (which uses `web.base.url`) when no website is resolvable from the request, session, or context. Backend flows with a real request still hit the company-aware branch. Steps to reproduce: 1. Install Email Marketing and Website. 2. Settings > Companies: create a second company B. Settings > Websites: ensure website A points to company A with domain A, and create website B for company B with domain B. 3. Settings > Technical > Parameters > System Parameters: set `web.base.url` to a third domain C, and add `web.base.url.freeze` = `True`. 4. On company A, Email Marketing: create a mailing with body `<a href="http://example.com">test</a>` and a recipient list, then click Send. 5. Settings > Technical > Automation > Scheduled Actions > "Mass Mailing: Process queue" > Run Manually. 6. Email Marketing > Configuration > Link Tracker: open the tracker generated for the mailing. => The Tracked URL uses domain A. => The Tracked URL uses domain C. Ticket [link](https://www.odoo.com/odoo/project.task/6038590) opw-6038590 Forward-Port-Of: odoo/odoo#259200
This update streamlines the process for adding tracked products with lots to the point of sale. Now, products using FIFO or LIFO removal strategies are automatically added to the cart without requiring users to manually select a lot. This simplifies the checkout experience and reduces potential errors.
Original PR description
Before this commit: ==== - The lot/serial selection popup was always shown when adding products tracked by lots. Following this commit: ==== - Products configured with FIFO/LIFO removal strategies are automatically assigned the corresponding lot and added directly to the cart without opening the selection popup. - If no removal strategy is configured, the existing lot selection behavior is preserved. task-6226577 Forward-Port-Of: odoo/odoo#273138 Forward-Port-Of: odoo/odoo#265708
A recent update to the SEPA XML processing for Sweden (l10n_se_bban) caused a test failure when both the account_iso20022 and l10n_se_bban modules were used. This commit resolves the test issue by temporarily skipping the failing test and adding a new test to ensure proper functionality.
Original PR description
Here https://github.com/odoo/enterprise/pull/114662 we changed the way the CdtrAgt node is used in the SEPA XML file for Sweden. But this change broke a test when both account_iso20022 & l10n_se_bban are installed, leading to a Non-expected child error. This commit skip the failling test if l10n_se_bban is installed, and add a new one to replace it. runbot-938366 runbot-938367 Forward-Port-Of: odoo/enterprise#122359 Forward-Port-Of: odoo/enterprise#121485
This fix resolves an issue where editing lot IDs on tracked products in the picking form caused unexpected quantity updates. The update ensures that lot assignments correctly adjust reservations, maintaining accurate stock levels and quantities, particularly when managing lot-tracked inventory. This improves the reliability of stock movements and reduces potential discrepancies.
Original PR description
### Issue: Editing the `lot_ids` of a move of a `lot` tracked product from the picking form view leads to wildly unexpected results. This happens only with tracking by `lot` not by serial. ###…
### Issue:
Editing the `lot_ids` of a move of a `lot` tracked product from the picking form view leads to wildly unexpected results. This happens only with tracking by `lot` not by serial.
### Concrete Issue 1:
1. In the settings Enable "Lots and serial numbers", "Storage Locations"
2. Create a storable product P tracked by lots
3. Create and confirm a delivery for 5 units of P
4. Set the quantity of the move to 5 from the Form picking view > save
5. Create and set 2 lots: LOT1, LOT2 on the serial numbers field
6. Save
#### > The quantity of the move has been updated to 2, only the first lot is set and it has been for this quantity of 2
### Concrete Issues 2 and 3:
1. In the settings Enable "Lots and serial numbers", "Storage Locations"
2. Create a storable product P tracked by lots
3. Update the onhand quantity of P:
- 1 units of LOT001 in Shelf1
- 2 units of LOT001 in Shelf2
- 2 units of LOT002 in Stock
4. Create and confirm a delivery for 5 units of P
5. Remove LOT002 from the Serial numbers in the Form picking view > save
#### > The quantity of the move is updated to 1 (only the 1 unit of LOT001 from Shelf2 is kept)
5'. Remove LOT002 and put it back
#### > The quantity is updated from 5 to 2 if you save, only LOT001 is kept.
### Cause of the issue:
The `_onchange_lot_ids` and `_set_lot_ids` methods have been tailored to work appropriately only with `serial` tracking, updating the quantities considering a 1 to 1 quantity, lot matching:
https://github.com/odoo/odoo/blob/c9715982134220aa8fa525d0cf6a8d47eaeb6ed6/addons/stock/models/stock_move.py#L623-L645
However, for lot tracked product the situation is much more subtle to handle.
### Behavior after the fix:
Editing the `lot_ids` on tracked products should adapt the reservation following these rules:
- Existing move lines with a valid lot or lot name should be kept unchanged.
- Removing a lot should delete its related move lines and adjust the move quantity accordingly.
- Each newly assigned lot must be linked to at least one move line of the move.
If the move is expected to bypass reservation (e.g. receipts, final move of a production,...):
- Assignment should be performed, in priority, on an existing free move line.
- If no suitable free move line exists, a new move line should be created with the largest possible quantity that does not cause the total assigned quantity to exceed the move demand.
- If such a quantity cannot be assigned, the new move line should be created with a quantity of 1 in the product.uom_id.
If the move is expected to be reserved (e.g. internal transfer, deliveries,...):
- Each new lot should be assigned from an existing quants with the maximum available quantity to satisfy at best the remaining demand.
- If no available quantity can be assigned from existing quants, the lot should be assigned a minimum quantity of 1 in product.uom_id.
### Additional note on the fix:
Since move that do bypass reservation use a different detailed operation view relying on lot_names form move line rather than lot_id from existing quants it is important to set both the `lot_name` as well as the `lot_id` on move lines for the changes to be visible in the detailed operations view.
### Note:
The current fix populated records on which the `label_production_view_pdf` report was tested (by the test_report) highlighting a template error:
https://github.com/odoo/odoo/blob/a73428187112b3948a11810abae2a3c82c9c7bcd/addons/mrp/report/mrp_production_templates.xml#L187
The value provided to the t-field being something else than a field but rather an or close between two fields.
opw-6173914
opw-5881661
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#263037This update corrects a bug in the Point of Sale system where global discount percentages with comma decimal separators (like in Dutch) were incorrectly applied. The fix ensures that discounts are calculated accurately based on the user's locale, preventing orders from being discounted to 100% instead of the intended percentage. This improves the reliability of the POS discount functionality.
Original PR description
When using Dutch (or similar locales where the decimal separator is a comma), a configured global discount percentage with decimals is misapplied in POS. For example, a default discount of 8,33% is…
When using Dutch (or similar locales where the decimal separator is a comma), a configured global discount percentage with decimals is misapplied in POS. For example, a default discount of 8,33% is shown in the discount popup as 8.33% and, when confirmed without editing, applies a 100% discount on the order instead of 8,33%. Steps to reproduce: ------------------- * Activate Belgian localization for accounting * Set the user language to Dutch (Netherlands) or Dutch (Belgium) * In Point of Sale settings, enable global discounts and set the default discount percentage to 8,33% * Open a POS session, add a product to the cart, and click Discount * Confirm the popup without changing the value > Observation: The popup displays 8.33% (with a dot). After confirmation, the order receives a full discount instead of 8,33%. Why the fix: ------------ The discount popup initialized its value with `String(discount_pc)`, which always uses a dot as decimal separator. POS then parses the input with locale-aware rules where `.` is the thousands separator, so "8.33" is read as 833 and capped to 100%. Format the default discount percentage with `formatFloat` so the popup starts with the correct localized value (e.g. "8,33"). opw-6334367 Forward-Port-Of: odoo/odoo#273022
This update corrects a bug in gift card redemption within Point of Sale (PoS). Previously, when the default tax setting was 'tax included,' gift card deductions were inaccurate. The fix ensures the correct value is deducted and displayed, maintaining accurate tax totals and preventing miscalculations.
Original PR description
We had a bug when redeeming a gift card when the default taxe of the company was tax_included. Steps to reproduce: ------------------- * Set default 15% tax to bo Tax Included * In PoS, sell a gift card * Use that gift card in a new order > Observation: Deducted amount is 43.48, that's 50 without taxes Why the fix: ------------ We now compute the gift card reward line from a tax-aware amount and choose the unit price based on whether the discount product’s tax is price-included, ensuring we deduct the full intended value while displaying the correct tax. This prevents under-deduction (untaxed base only) and avoids re-adding tax on top, keeping totals and tax lines consistent. opw-5441106 Forward-Port-Of: odoo/odoo#244735
This update resolves an issue where header text on mobile was too dark against the background, making it difficult to read. The fix corrects a conversion error that prevented the correct CSS from applying to the header, ensuring optimal color contrast and readability for users. This improves the overall user experience.
Original PR description
Steps to reproduce: - Set the header position to "Over the Content" - Set the background color to the last preset (dark) - Go to mobile view => If you are at the top of the page when opening the menu, the text is too dark to be readable. When the conversion from publicWidget to interaction was done, a mistake was made when converting HeaderGeneral. `o_top_menu_collapse_shown` was not toggled on `header#top` anymore. Therefore some css was not applied, leading to issues with the color constrasts. This commit fixes this issue by fixing the selector in dynamicContent. task-6311038 Forward-Port-Of: odoo/odoo#271410 Forward-Port-Of: odoo/odoo#270560
This update corrects a bug where negative forecast quantities could cause issues in the MRP planning process. The fix ensures that any remaining negative forecast demand is correctly added to the first forecast period, resolving a data inconsistency. This improves the reliability of production planning forecasts.
Original PR description
Steps to reproduce: - Fresh DB - Add a negative number to the forecast demand in the last period Cause: A variable was used without declaration Fix: According to odoo/enterprise#56128, it was intended that any remaining negative quantity to add should be added to the first forecast. Forward-Port-Of: odoo/enterprise#122261
This update ensures that invoice PDFs automatically translate the recipient's address (like VAT numbers) into the customer's preferred language. Previously, the system wasn't correctly applying language settings to PDF reports. This improves the user experience and compliance with local regulations.
Original PR description
We currently set the recipient address before we rebrowse the related records. It is therefore not translated into the recipient's language.
Steps to reproduce on Runbot:
1. Set the language of the user to English.
2. Install the l10n_es localization with demo data.
3. Switch to the ES company.
4. Create an invoice for a customer with a VAT number.
5. Set the language of that customer to Spanish.
6. Print the PDF.
The sender address `vat_label` is correctly translated to "NIF", but the `vat_label` of the recipient address remains in English: "VAT".
Ticket [link](https://www.odoo.com/odoo/project.task/6193141)
opw-61931415 changes
Resolved issues and error corrections
Warehouse staff can now scan a package as the destination package during picking even when that package already contains other products. This prevents an incorrect error from blocking normal barcode workflows when extra products are not allowed for the operation.
Original PR description
### Steps to reproduce: - In the settings Enable: Multi-steps Routes, Packages - Put your warehouse in delivery in 2-steps - On the Pick operation type in the barcode tab disable: "Allow extra…
### Steps to reproduce: - In the settings Enable: Multi-steps Routes, Packages - Put your warehouse in delivery in 2-steps - On the Pick operation type in the barcode tab disable: "Allow extra products" - Create two storable products P1 and P2 - On P2 > On hand > Update Quantity > New - Create a new line in WH/Output with a package POOK for 1 unit - Create a new internal transfer for 1 unit of P1 using the pick operation type so that the picking goes WH/Stock -> WH/Output - Set the quantity of the move to 1 unit and go to the barcode app - Open the Pick > Scan WH-STOCK > Scan P1 > Scan POOK #### > An error is raised: This package contains extra products and extra products are not allowed on this operation. #### Expected behavior: The package should be set as result package. ### Cause of the issue: In the `_processPackage`, a check that is done to ensure that the package scan will not add extraproduct to the picking if this operation is not allowed: https://github.com/odoo/enterprise/blob/5e4c8ecb0c644e21755570ed59cd8f6e9f618c8a/stock_barcode/static/src/models/barcode_picking_model.js#L2024-L2035 Unfortunately, this check is done just before a possible usage of the package as package dest. And, in that case, since we do not try to add any product to the picking the check is irrelevant anyway. opw-6303969 Forward-Port-Of: odoo/enterprise#121789
This update corrects a problem that prevented demo data from loading correctly in the Russian localization (l10n_in) module. The fix ensures the system properly handles company IDs, resolving an error that occurred when the data was initially received. This ensures demo data loads reliably for users.
Original PR description
Currently, an exception is raised while loading demo data because `companies` is received as an integer id instead of a company recordset. Error: `AttributeError: 'int' object has no attribute 'filtered'` This commit fix the above issue by checking whether `companies` is a `models.BaseModel` instance and, if not, converting it to a recordset using browse(). No Task ID
This update resolves an issue where self-ordering table references were being lost when a self-order was created. The fix ensures that the original table link is maintained, allowing users to correctly validate and pay orders placed via QR codes. This improves the reliability of the self-ordering mobile experience.
Original PR description
Steps to reproduce: --------------- - Enable QR Menu & Ordering in POS - Enable Service at Table - Create a self-order from a table QR - Validate/pay the order from the POS Cause: ----------- The write override unconditionally `table_id` to `self_ordering_table_id`, even when `table_id` was falsy, clearing the original self-order table link. Fix: ---------- Only update `self_ordering_table_id` when `table_id` is explicitly set and truthy. Task-6272642 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268459
This update corrects a technical error within the l10n_fr_pdp module that was causing incorrect reporting related to French tax flows. The fix prevents a faulty SQL query from being executed when a specific date calculation fails, ensuring accurate financial data processing for French businesses using Odoo.
Original PR description
Fixes _force_update_l10n_fr_f10_moves(). It would create a SQL query that compares a date to a bool when _pdp_get_flow_10_start_date() returned None. Forward-Port-Of: odoo/odoo#273006
This update fixes an issue where customer addresses were excessively long in form view titles and breadcrumbs, making them difficult to read. The change now only displays the customer's name, aligning with how other related fields are displayed, resulting in a cleaner and more user-friendly navigation experience.
Original PR description
- Create a new Invoice; - Assign a Customer with a multiline address; - Click on the internal link (arrow icon) of the Customer field. Before this commit, the form view title and the breadcrumb would contain not only the customer's name but also their full address. This resulted in an excessively large and unreadable breadcrumb. Now, only the name is retained. This commit applies the same behavior already used in many2one fields: the display name is split by line breaks, and only the first line is kept for the title and breadcrumb. task-id 6329662 Forward-Port-Of: odoo/odoo#272550 Forward-Port-Of: odoo/odoo#272059
9 changes
Resolved issues and error corrections
This update resolves a technical problem that could have caused incorrect updates to French tax reporting data. The fix prevents a query from failing when a specific date field was empty, ensuring accurate tax calculations and reporting for French businesses using the Odoo platform. This improves the reliability of our French tax compliance features.
Original PR description
Fixes _force_update_l10n_fr_f10_moves(). It would create a SQL query that compares a date to a bool when _pdp_get_flow_10_start_date() returned None. Forward-Port-Of: odoo/odoo#273006
This update fixes an issue where URL suggestions in the Notes app overflowed on smaller mobile devices. The fix adjusts the layout of the suggestion container to ensure it adapts to different screen sizes, providing a cleaner and more usable experience for users.
Original PR description
Step to reproduce: - Open Notes - Open the link popover - Type a URL in the URL input field Description of the issue/: - On mobile devices, URL autocomplete suggestions overflow the viewport. Cause: - The autocomplete suggestions container has a max-width of 600px. - On smaller screens, the container does not shrink to fit the available width, causing it to overflow the viewport. Solution: - Add width: 100% to the autocomplete suggestions container so it adapts to the available screen width on smaller devices while still respecting the existing max-width on larger screens. task-6201175 Forward-Port-Of: odoo/odoo#269493
This update fixes an issue where customer addresses were excessively long in form view titles and breadcrumbs, making them difficult to read. The change ensures that only the customer's name is displayed, aligning with how other fields are handled, resulting in a cleaner and more user-friendly navigation experience.
Original PR description
- Create a new Invoice; - Assign a Customer with a multiline address; - Click on the internal link (arrow icon) of the Customer field. Before this commit, the form view title and the breadcrumb would contain not only the customer's name but also their full address. This resulted in an excessively large and unreadable breadcrumb. Now, only the name is retained. This commit applies the same behavior already used in many2one fields: the display name is split by line breaks, and only the first line is kept for the title and breadcrumb. task-id 6329662 Forward-Port-Of: odoo/odoo#272550 Forward-Port-Of: odoo/odoo#272059
This update fixes an issue where the Intrastat report was incorrectly cropping the bill name, preventing full visibility of key information like the hyphenated identifier. The fix adjusts a regex pattern to allow hyphens in bill names, ensuring accurate display of all bill details in the report.
Original PR description
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] *…
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] * Intrastat Country: [any] * Intrastat Transport Mode: [any] - Confirm the bill - Make sure that the bill name contains a hyphen character (i.e. "-") For example, "BILL/2026-06/0001". Use the "Resequence" action from the bills list view if needed. - Go to "Accounting / Reporting / Audit Reports / Intrastat Report" - Expand the line to display the bill name **Issue:** The bill name is not fully displayed. It is cropped right before the hyphen character (i.e. BILL/2026). **Cause:** A regex is used to retrieve the bill name from the report line name, but it is only allowing "/" character. **Solution:** Just allow "-" character in addition. No other character is allowed to limit the risk of matching something that should not. opw-6299854 Forward-Port-Of: odoo/enterprise#120979
A technical issue prevented users from previewing the '2Fa New Login' template. This was caused by an assertion error triggered when the preview environment wasn't running with elevated privileges. The fix replaces the assertion with a conditional check that returns placeholder data, allowing the preview to function correctly.
Original PR description
Issue: ---------------------------------------- Clicking "Preview" on the template "2Fa New Login" causes an error. Steps to reproduce: ---------------------------------------- - Search for the mail template "Settings: 2Fa New Login" - Click "Preview" - Error in terminal - From 17.0+ the error shows in UI - From saas-18.3+, a traceback occurs whe resetting the template Cause: ---------------------------------------- There is an assert the method `_get_totp_mail_code()` to ensure it's used during 2FA. But when passing by rendering this template in preview we aren't in sudo and the assert in `_get_totp_mail_code()` raises. Solution: ---------------------------------------- We replace the `assert` by a `if` which will return fake results. opw-6333887 Forward-Port-Of: odoo/odoo#273505 Forward-Port-Of: odoo/odoo#273125
This update fixes an issue where users weren't receiving notifications when a sign request was completed after they selected 'Handle in Odoo' (inbox) for notifications. The change ensures that the sender receives a notification, improving transparency and workflow efficiency for sign requests. This was a bug impacting the sign process.
Original PR description
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign*…
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign* (`sign`) 2. Sets the current user's notification preference to "Handle in Odoo" (`inbox`) 3. Create a sign request and send it to Marc Demo 4. As Marc Demo, sign the request 5. **The user who sent the sign request did not receive a notification to notify them that the request was signed.** ## Fix This is a partial backport of both https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda (saas-18.2) and a related fix https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 (19.0). Before the first commit, users would not receive inbox notification when sign requests would be completed. ## Note to reviewer The issue only occurs in 18.0, as it is fixed by https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda in 18.2, but we can backport the fix from https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 from 18.2 to 18.4 if desired. opw-6251702 Forward-Port-Of: odoo/enterprise#122519 Forward-Port-Of: odoo/enterprise#120740
This update resolves an issue where server reloads triggered by file changes could cause the application to crash. The fix prevents a series of signals from interrupting the server's restart process, ensuring stability and preventing service interruptions during updates. This improves the reliability of the Odoo server.
Original PR description
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP`…
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP` into `KeyboardInterrupt`, which `ThreadedServer.run()`'s wait-loop catches. The catch is too narrow — a reload `SIGHUP` can kill the process through **three** windows that all sit outside the wait-loop's `try/except`, so the exception escapes `run()`/`main()`. Under Docker's default `restart: no`, PID 1 dies and the container stays down. ### The three windows 1. **Teardown duplicate (exit 130).** One file change can emit several FS events; the FSWatcher's `if not odoo.phoenix:` dedup races across threads and fires more than one `SIGHUP`. The first begins the phoenix teardown; the second lands during `stop()` / `watcher.stop()` / `_reexec()` and `KeyboardInterrupt` escapes. 2. **Exec-gap (exit 129).** `os.execve()` resets caught signal handlers to their default disposition (`SIGHUP` terminates) but preserves `SIG_IGN`; a `SIGHUP` arriving after the exec but before the re-exec'd process re-installs its handler kills the process outright. 3. **Startup (exit 130).** In the re-exec'd process, a `SIGHUP` anywhere in the startup section that precedes the wait-loop — `start()`, `preload_registries()` **and** `cron_spawn()` — escapes `run()`. ### Reproducer (deterministic) Boot a `ThreadedServer` (`--workers 0`) on any initialised db, then signal PID 1 a few times in quick succession: ```bash docker exec <container> sh -c 'i=0; while [ $i -lt 8 ]; do kill -HUP 1; sleep 0.1; i=$((i+1)); done' ``` Unpatched the process exits 130 or 129. Patched it stays up after one clean phoenix reload. Verified live on 17.0 and 18.0: stock `server.py` dies; the patched `server.py` survives sustained bursts (20/20 across repeated reload cycles on each version); `SIGINT`/`SIGTERM` still exit 0. ### Fix Minimal, in `signal_handler` + `run()` + `_reexec()`; `SIGINT`/`SIGTERM` untouched; one new instance attribute, no new module globals: - **Teardown duplicate:** ignore a `SIGHUP` once `quit_signals_received` is set (a restart/shutdown is already pending; the re-exec reloads fresh code). - **Startup:** a per-instance `in_preload` flag marks the entire startup section (`start()` + `preload_registries()` + `cron_spawn()`); a `SIGHUP` there sets the phoenix flag + counter and returns instead of raising, so the wait-loop exits right after startup and runs the normal restart. - **Exec-gap:** `signal.signal(signal.SIGHUP, signal.SIG_IGN)` just before `os.execve` so a `SIGHUP` in the gap is dropped rather than terminating the process. ### Related - #21209 (merged) — introduced the phoenix flag; did not guard these windows. - #206898 (merged), #207930 (open) — PreforkServer reload. ### CLA Covered by Codeforward B.V.'s corporate CLA; #269240 adds me to its contributor list (pending merge). Forward-Port-Of: odoo/odoo#269247
This update resolves a rare technical problem within the Odoo web interface that could occasionally cause a test to fail. The fix ensures that popovers are properly closed, preventing errors that arise when components are destroyed during the testing process. This improves the stability of the web application.
Original PR description
Add an extra step to close the popover and prevent the `Component is destroyed` error[1], which can happen during hoots cleanup, similar to the issue we see when some dialogs perform RPCs as they are being destroyed. [1]: https://runbot.odoo.com/runbot/build/115972540 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273396 Forward-Port-Of: odoo/odoo#273085
This update fixes an issue where new time off requests were incorrectly showing a duration of 0 days due to an automation rule. The fix ensures the leave duration is accurately calculated from the requested dates, regardless of automation activity creation. This prevents incorrect time off calculations and reporting.
Original PR description
Current behavior: -- With an active automation rule (base_automation) whose action creates an activity (e.g. a "Time Off Approval" activity) on hr.leave creation, every newly created time off request…
Current behavior: -- With an active automation rule (base_automation) whose action creates an activity (e.g. a "Time Off Approval" activity) on hr.leave creation, every newly created time off request has a duration of 0 days / 0 hours, regardless of the requested dates. Expected behavior: -- The leave duration is computed from the requested dates, unaffected by the presence of an activity-creating automation rule. Steps to reproduce: -- - Create an automation rule on hr.leave, trigger "On Creation & Update". - Add an action that creates an activity (type "Time Off Approval"). - Create any time off request for an employee with a working schedule. - The request shows a duration of "0 days" (or "0 hours"). Cause of the issue: -- date_from/date_to and number_of_days/number_of_hours are stored compute fields the duration (number_of_days/number_of_hours) depends on the dates (date_from/date_to). The rule's action creates a mail.activity whose notification renders the leave's display_name. Computing display_name pulls in dashboard_warning_message, which re-enters _compute_date_from_to. Inside that in-progress compute, _compute_duration is evaluated while date_from/date_to are still False in the ORM cache, so _get_durations returns (0, 0). The dates are correct afterwards, but the duration was already computed and stored as 0, and nothing in the create flow re-triggers its compute, so a stale 0 is persisted to the database (it is only recomputed if a dependency such as the request dates or leave type is later modified). Fix: -- Once date_from/date_to are settled at the end of _compute_date_from_to, add the duration fields (number_of_days, number_of_hours, duration_display) back to the compute queue so they are recomputed against the correct dates. opw-6235902 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
19 changes
New functionality added to Odoo
Odoo can now use official daily exchange rates from the Central Bank of Azerbaijan for automatic currency updates. This helps businesses using AZN keep multi-currency accounting and tax transactions aligned with official rates, including currencies quoted in larger nominal units.
Original PR description
This commit adds the Central Bank of Azerbaijan (CBA) as a supported service provider for automatic currency rate updates. Purpose: To ensure multi-currency accounting entries and taxable transactions are accurately translated into the national currency (AZN) using the official exchange rate defined by the CBA for the transaction day. Functionality: -Enables fetching official daily exchange rates directly from CBA via XML. -Automatically handles rates defined for different nominal quantities (e.g., rates quoted per 100 units instead of 1 unit). task-6112867
Enhancements to existing features
Senders using Sign Now for documents with multiple signers can now choose whether each remaining person signs immediately or receives their signing link by email. This makes in-person signing sessions more flexible and clearly confirms that the request will finish once emailed recipients complete their part.
Original PR description
When signing locally for multiple signers, the sender can now choose, for each remaining signer, to sign on the spot or send them the link by email. Once every signer has been handled, a confirmation dialog lets the sender know the request will complete as the emailed signers sign on their side. task-6234594
VoIP demo mode now only allows administrators to place demo calls, helping prevent unintended use by regular users. The VoIP dashboard is also simplified by removing a production filter that was not useful in live environments.
Original PR description
1. Only allow voip admin to make demo calls in demo mode 2. remove the default is_producion filter in dashboard since it's useless in production. Task-6304061
French fiscal declaration exports now run additional validation before submission. This helps ensure required company, debtor, writer, and partner information is complete and that ambiguous report choices are resolved before the file is sent.
Original PR description
while exporting liasse fiscale, no chceks were done before the export and there were no account returns checks before sending it, this commit add account return checks to the liasse fiscale: -writer and debtor have the necessary informations on their record -partners mentionned in the reports have the necessary fields completed on their records -for some line, we have to choose between some values task-6127270 Forward-Port-Of: odoo/enterprise#115812
This update improves Japanese tax reporting within Odoo Enterprise by incorporating the two distinct types of Japanese Consumption Tax Returns (JCT) – Accumulation and Deduction. This change aligns Odoo with updated Japanese tax regulations, ensuring accurate reporting and compliance.
Original PR description
Replace the single generic Japanese return type with the two JCT return types, Accumulation and Deduction, pointing at the new sectioned reports in l10n_jp. task-4490922
Resolved issues and error corrections
Payroll run creation now keeps the selected branch company instead of falling back to the main company. This prevents blocking warnings and supports accurate payroll processing for branch employees, including Hong Kong payroll flows.
Original PR description
[FIX] hr_payroll: fix correct company selection in payrun (branch case) Bug reproduc: 1 - Select 19.3 or master -> Open a branch to belgium company -> create an employee in that branch 2 - In your…
[FIX] hr_payroll: fix correct company selection in payrun (branch case)
Bug reproduc:
1 - Select 19.3 or master -> Open a branch to belgium company -> create an employee in that branch
2 - In your env, select both belgium and its branch, payroll->payrun->select branch as a company.
3 - Continue till the end of payrun creation, you will get warning (blocked) due to wrong company selection, main belg company is selected instead of branch
Bug cause:
1 - In selectEmployees function of hr_payslip_run_form, in the raw_record the company_id is passed as integer.
2 - In buildRawRecord function of hr_version_list_controller, we are assigning company_id as raw_record's company_ids id, but company id was already integer, company_id.id is undefined
3 - Since undefined is passed to the company_id, it uses the self.env.company_id as a default in the creation of hr payrun that cause to the error.
Bug fix:
1 - In the buildRawRecord function of hr_version_list_controller, I just assigned the company_id because it is already integer and all problem is solved.
task - 6326117
Forward-Port-Of: odoo/enterprise#122538
Forward-Port-Of: odoo/enterprise#121505Belgian payroll now handles cases where a student minimum wage salary scale cannot be found without causing the calculation to fail. This helps payroll teams avoid unexpected errors and keeps wage checks running reliably.
Original PR description
When computing _get_student_min_wage and the specific salary scale is not found, it returns None and then fails in the tuple compression as None is not an interable. task-6318004 Forward-Port-Of: odoo/enterprise#122500 Forward-Port-Of: odoo/enterprise#121392
Fixes a point of sale issue where deleting an order line with a custom product attribute could make the kitchen preparation display go blank. The display now stays available and continues showing the order information it can safely resolve, reducing disruption for kitchen staff.
Original PR description
When an order is sent to the preparation display and one of its products has an attribute with a custom (free text) value, completely deleting that line in the PoS makes the whole preparation display…
When an order is sent to the preparation display and one of its products has an attribute with a custom (free text) value, completely deleting that line in the PoS makes the whole preparation display crash and show a blank white screen, so the kitchen can no longer see any order. Steps to reproduce: ------------------- * Configure a PoS product with an attribute whose variant that has a custom (free text) value. * In the PoS, add the product, select that attribute value and send the order to the preparation display. * Back in the PoS, completely delete that order line (do not just set its quantity to 0) and send the order to the preparation display again. > Observation: The preparation display crashes and only a white screen is shown. The browser console reports "TypeError: Cannot read properties of undefined (reading 'id')". Why the fix: ------------ Completely deleting the line deletes the source pos.order.line, so the preparation line that is still displayed no longer resolves its `pos_order_line_id`. While building the attributes to display, the orderline component dereferenced `.id` on that (now undefined) relation, as well as on the related custom value records, which threw and brought down the whole preparation display instead of only that line. We now guard those relations: when the originating order line is gone, the unresolvable custom value is simply dropped and the attribute is still shown, keeping the preparation display alive. opw-6282607 Forward-Port-Of: odoo/enterprise#122691 Forward-Port-Of: odoo/enterprise#121194
This update fixes an internal test setup issue in the Urban Piper point-of-sale integration. It keeps test-only changes properly contained, helping maintain code quality checks without affecting day-to-day users.
Original PR description
Avoid polluting the Odoo model registry and failing `test_lint_override_signature` by using `patch.object` instead of manual assignment. This ensures the injected method is properly torn down after the test block, keeping the registry clean and bypassing static analysis failure as the patched method is only used for tests. runbot-939298 Forward-Port-Of: odoo/enterprise#122446 Forward-Port-Of: odoo/enterprise#122283
This update corrects automated test coverage for Swedish SEPA payment files when related payment modules are installed together. It helps ensure Sweden-specific bank payment exports remain validated without false test failures.
Original PR description
Here https://github.com/odoo/enterprise/pull/114662 we changed the way the CdtrAgt node is used in the SEPA XML file for Sweden. But this change broke a test when both account_iso20022 & l10n_se_bban are installed, leading to a Non-expected child error. This commit skip the failling test if l10n_se_bban is installed, and add a new one to replace it. runbot-938366 runbot-938367 Forward-Port-Of: odoo/enterprise#122599 Forward-Port-Of: odoo/enterprise#121485
This update resolves issues with knowledge tours and web_studio's Powerbox functionality. By inserting a forward slash into the DOM and adjusting event handling, the system now correctly simulates Powerbox opening, ensuring tours function as expected and web_studio's editing features are reliable.
Original PR description
#### Description of the issue: - Since the search powerbox plugin now checks for the actual existence of `/` in the DOM, some knowledge tours were failing because only the input event was dispatched without inserting `/`. - In web_studio, `insertText` was not positioning the selection correctly after insertion and was not dispatching beforeinput event before the DOM insertion. #### After this commit: - Adapt the `openPowerbox` utility in knowledge to insert `/` in the DOM before opening the powerbox. - Dispatch `beforeinput` before DOM insertion and `input` after it in web_studio, and move the selection after the inserted text. Community PR-https://github.com/odoo/odoo/pull/266284 task-6243724 Forward-Port-Of: odoo/enterprise#118310
This update fixes an issue where customer names weren't being correctly displayed in Odoo bookings created through Reserve with Google. Now, when booking through Google, the customer's full name (first and last) is used instead of just their email address, improving the user experience and contact information accuracy.
Original PR description
When a customer books through Reserve with Google, the createBooking payload carries the booker given_name and family_name next to the email, but the handler passed only the normalized email to…
When a customer books through Reserve with Google, the createBooking payload carries the booker given_name and family_name next to the email, but the handler passed only the normalized email to _mail_find_partner_from_emails. The new res.partner was therefore created with its name falling back to the email, see https://github.com/odoo/odoo/blob/aa7b5921191a0ff53ef1cc32af99fe458c45c0da/addons/mail/models/res_partner.py#L177 That name then flows into the calendar.event name, the attendee common_name and the contact details, all showing the email instead of the customer name. The module has read neither field since it was added in https://github.com/odoo/enterprise/commit/2e855b910173b56e8501d0ebe9ee6f83ac5845bc. Build the booker name from given_name and family_name and pass it with the email through formataddr in google_reserve_booking_create, so a newly created partner is named after the customer. A partner matched on an existing email keeps its current name. Steps to reproduce: 1. Enable Reserve with Google on an appointment type. 2. Book a slot from Google Maps with given name John and family name Doe. 3. Open the created booking and its contact in Odoo. => the contact name is the email instead of John Doe Ticket [link](https://www.odoo.com/odoo/project/49/tasks/6232318) opw-6232318 Forward-Port-Of: odoo/enterprise#120604
This update fixes an issue where the withholding tax return was incorrectly combining balances with regular tax returns. The change ensures the withholding tax return accurately calculates the independent balance due, resolving a discrepancy in reported tax liabilities for Italian companies. This improves the accuracy of tax reporting.
Original PR description
Steps to reproduce: - setup an Italian company - make an invoice (for example in May) with a withholding tax and make a transaction to pay it - generate tax returns (opening date in June so that it generates from May) - validate regular tax return for May - validate withholding tax return for May -> The withholding tax return shows an amount to pay with a balance that is a combination of both the regular tax return and the withholding one, while it should be independent of the regular one. task-6116304 Forward-Port-Of: odoo/enterprise#121254 Forward-Port-Of: odoo/enterprise#119375
A recent update removed a dependency and added a new project field to improve data accuracy. This change resolved a test failure (test_fsm_flow) that indicated missing project information. The update ensures correct project data is fetched within the planning module.
Original PR description
Currently, running test `test_fsm_flow` leads to a Attribute Error: `planning.slot' object has no attribute 'project_id'`. This happens because project_id field removed in this PR: https://github.com/odoo/enterprise/pull/113153 This field is removed to remove `project_timesheet_forecast_sale` module in the dependencies of `planning_field_service_sale_timesheet` module and add a project field in settings of planning when Billing feature of field service is enabled. Related PR: https://github.com/odoo/enterprise/pull/83012 runbot-[941219](https://runbot.odoo.com/odoo/error/941219) Forward-Port-Of: odoo/enterprise#122442
This update ensures that only complete and accurate address data is sent to Fiskaly when creating POS certificates. Previously, placeholder values like 'N/A' were included, which is now corrected to omit fields when data isn't available, streamlining the process and improving data quality. This change enhances integration with Fiskaly and reduces potential errors.
Original PR description
In this commit: ------------------- - Buyer address fields are optional and should only be sent to Fiskaly when they are actually available. - Avoid sending placeholder values like "N/A". If the data is not present, the fields should simply be omitted from the request. task: 6113133 Forward-Port-Of: odoo/enterprise#122188 Forward-Port-Of: odoo/enterprise#113621
Features or functions removed from Odoo
This update removes a previously deleted file that was causing a 'dead' module in the Odoo Enterprise system. The change ensures the system is cleaner and more stable, addressing a minor technical issue. This improves overall system performance.
Original PR description
The contents of this file were previously deleted, but the file itself was missed, leaving a dead l10n_hk_hsbcnet module in 19.4. This commit removes the file entirely to clean it up. Forward-Port-Of: odoo/enterprise#122573
This update removes outdated code related to 'onWillRender' hooks, a component of the older Owl 3 system. This change is part of a larger migration to Owl 3, ensuring the system continues to function correctly and efficiently. It's a routine maintenance update.
Original PR description
As part of the Owl 3 migration, replace deprecated onWillRender hooks with the appropriate Owl 3 alternatives.
Code cleanup and technical improvements
This update aligns several Enterprise apps with the latest underlying Odoo web interface changes. It helps keep features such as Gantt views, Studio, Documents, Sign, Social, Planning, and related workflows working reliably after the platform upgrade.
Original PR description
## `t-ref` → Owl 3 signals — enterprise companion Enterprise side of the codebase-wide Owl 2 → Owl 3 ref-semantics migration. Pairs with the consolidated community PR. Single squashed commit (16 files): xpath rewrites for removed `t-custom-ref` attributes, ref reads converted to the signal call form, and patch/subclass reusers adapted across `web_gantt`, `web_studio`, `documents`, `ai`, `sign`, `social`, `l10n_ke_edi_oscu_pos`, `planning`, `hr_holidays_gantt`. ### Notes - Rebased onto current enterprise `master` (2026-06-10). - Community PR: odoo/odoo#269265
This update removes outdated code related to a previous Gantt chart progress bar redesign. The progress bar component is no longer needed in the current layout, so these files have been deleted to streamline the system and improve efficiency. This is a routine maintenance task.
Original PR description
Cleans up residual dead code left over from the progress bar redesign in https://github.com/odoo/enterprise/pull/118045. Since the `GanttRowProgressBar` component is no longer referenced anywhere in the new layout architecture, its corresponding files have been deleted. Forward-Port-Of: odoo/enterprise#122142
12 changes
Resolved issues and error corrections
Fixed an issue where bank reconciliation rules that read amounts from transaction labels could fail or create incorrect journal entry balances for foreign-currency bank journals. The extracted amounts are now converted to the company currency, helping prevent reconciliation errors and inaccurate accounting entries.
Original PR description
### Issue: When a bank journal uses a foreign currency, reconciliation model lines with `Amount Type: From Label` (regex) could raise a constraint error or produce incorrect balances on the journal…
### Issue: When a bank journal uses a foreign currency, reconciliation model lines with `Amount Type: From Label` (regex) could raise a constraint error or produce incorrect balances on the journal entry ### Cause: The `balance` of the generated move line was set to the raw value extracted by the regex, without converting it from the journal currency to the company currency This violated the sign constraint between `balance` and `amount_currency` when the exchange rate caused a mismatch, raising a `_check_amount_currency_balance_sign` error The `amount_currency` was already correctly set Only the `balance` conversion was missing ### Steps to reproduce: - Install `accountant` - Enable a foreign currency (e.g. EUR) with two rates: yesterday: ratio < 1 (e.g. 0.5), today: ratio > 1 (e.g. 2.0) - Create a Bank journal in EUR - Open Bank Reconciliation for that journal - Add two transactions (one dated yesterday, one today) (Ref: "test BANK:0001690,00EUR EXP:00033,80", amount: 1656.20) - Create a reconciliation model (3 dots > Manage Models) (name: From Label): -- Account: 101401 Bank, Amount: BANK:0*(\d+),(\d+) -- Account: 600000 Expenses, Amount: EXP:0*(\d+),(\d+) - Apply the model on both transactions Before the fix, one raised an error due to the constraint violation - From the list view, open the Journal Entry for the other transaction Before the fix, `balance` was not converted to company currency opw-6292839
The Sales Commission Achievement report no longer crashes when users apply filters based on relative dates such as the current period. This keeps commission reporting usable and reliable for common date-based searches.
Original PR description
### Issue Applying a filter using relative date expressions (e.g. `today`) on the Sales Commission Achievement report raises a traceback. ### Steps to reproduce 1. Open **Sales > Commissions > Achievements**. 2. Apply the **Current Period** filter. ### Current behavior The report crashes with: ```text ValueError: time data 'today' does not match format '%Y-%m-%d' ``` ### Cause The `_search` implementation extracts `date_to` values from the search domain and assumes they are literal `%Y-%m-%d` strings. However, search domains may contain relative date expressions such as `today`, `today +1d`, `today =1m`, etc., which cannot be parsed using `datetime.strptime()`. ### Fix Convert the incoming search domain to a `Domain` object and resolve it with `optimize_full()` before extracting the `date_to` values. This evaluates relative date expressions into actual `date` objects, preventing the traceback while preserving the existing currency conversion date logic.
Users who choose to handle notifications in Odoo now receive an inbox alert when a signature request they sent is completed. This helps request owners stay informed without relying on email notifications.
Original PR description
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign*…
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign* (`sign`) 2. Sets the current user's notification preference to "Handle in Odoo" (`inbox`) 3. Create a sign request and send it to Marc Demo 4. As Marc Demo, sign the request 5. **The user who sent the sign request did not receive a notification to notify them that the request was signed.** ## Fix This is a partial backport of both https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda (saas-18.2) and a related fix https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 (19.0). Before the first commit, users would not receive inbox notification when sign requests would be completed. ## Note to reviewer The issue only occurs in 18.0, as it is fixed by https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda in 18.2, but we can backport the fix from https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 from 18.2 to 18.4 if desired. opw-6251702 Forward-Port-Of: odoo/enterprise#122519 Forward-Port-Of: odoo/enterprise#120740
The Intrastat report now correctly displays bill names that include hyphens, such as monthly sequence numbers. This prevents truncated bill references in audit reporting and makes it easier for users to identify the correct accounting document.
Original PR description
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] *…
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] * Intrastat Country: [any] * Intrastat Transport Mode: [any] - Confirm the bill - Make sure that the bill name contains a hyphen character (i.e. "-") For example, "BILL/2026-06/0001". Use the "Resequence" action from the bills list view if needed. - Go to "Accounting / Reporting / Audit Reports / Intrastat Report" - Expand the line to display the bill name **Issue:** The bill name is not fully displayed. It is cropped right before the hyphen character (i.e. BILL/2026). **Cause:** A regex is used to retrieve the bill name from the report line name, but it is only allowing "/" character. **Solution:** Just allow "-" character in addition. No other character is allowed to limit the risk of matching something that should not. opw-6299854 Forward-Port-Of: odoo/enterprise#120979
Bank reconciliation partner search now includes contacts owned by a selected branch company's parent company, as well as global contacts. This helps multi-company users find the right customer or vendor when matching bank transactions, reducing manual work and reconciliation errors.
Original PR description
When setting a partner from the bank reconciliation control panel, the partner lookup domain only considered global contacts and contacts directly linked to the selected company IDs. This caused a multi-company issue for branch companies, where users could not find contacts owned by their parent company. The domain is now updated to include: Global contacts (company_id = false) Contacts whose company is a parent of the selected companies (company_id parent_of companyIds)
The timesheet grid now correctly marks non-working days as unavailable when employees view their own timesheets. This helps users avoid entering time on days that are outside their personal working schedule.
Original PR description
To reproduce: ============= - modify Mitchel Admin's working schedule and remove a day of work - open timesheet app as Mitchel Admin - the removed day is not grayed out as unavailable Porblem: ======== the method `get_unavailabily` was handling only the case when calling it with `groupby=employee_id` otherwise it returns the company's unvailability Solution: ========= when the "My Timesheet" action is opened, the method `get_unavailabily` is now called with a specific context key, allowing to return the current user's unavailability instead of the company's one. opw-5949236 Forward-Port-Of: odoo/enterprise#122543 Forward-Port-Of: odoo/enterprise#113984
This update resolves a problem preventing bulk product imports when recurring invoices are used. A recent change attempted to use a helper function, but it wasn't properly ported to the 19.0 version of Odoo. This fix restores the missing function, allowing products to be imported correctly.
Original PR description
The port https://github.com/odoo/enterprise/commit/68640b5bddf51a8cbf58d3af3628cd4b57e08913 added a call to self._get_confirmed_order_lines() in product.template.write() (on import, when recurring_invoice changes), but the helper itself was never ported to 19.0. Importing products in bulk then fails with AttributeError: 'product.template' object has no attribute '_get_confirmed_order_lines'. Restores the method from master (PR https://github.com/odoo/enterprise/pull/117046) at the end of the ProductTemplate class.
This update ensures that work orders are properly updated when a product's bill of materials (BOM) is modified – specifically, when an operation is deleted or changed. Previously, the system didn't always unlink related work orders, leading to inconsistencies. This fix resolves this issue by correctly updating work orders linked to the BOM.
Original PR description
Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first operation…
Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first operation on anything else than the company, name or workcenter - Go back to the MO, click the "Update Bom" button > The second operation is not unlinked and the first operation is not updated Cause of the issue: The `action_update_bom` updates the move raws and operations of the MO via the `_link_bom`: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L1214-L1218 For draft MO's all the work of these updates is done via the compute methods and by deleting all the records unrelevant to the new bom: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2603-L2626 And, in that case all the workorders that are not linked to an operation of the bom are expected to be deleted. However, when the MO is not in draft, the update of operations is expected to be performed here: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2647-L2664 However, since the operation of the bom has been deleted, the workorder that is expected to be deleted is not linked to any operation and hence does not satisfy the condition to be deleted: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2663-L2664 Concerning the non update of operations, it happens because the MO's operation are only updated on the three fields: `company_id`, `workcenter_id`, `name`: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/mrp/models/mrp_production.py#L2647-L2664 https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/mrp/models/mrp_production.py#L2628-L2629 However, many other cahnges can and are actually relevant. Note: Prior to commit 80e6ed658fb43584bc2fad673ca40d9af6cf0ab6 operations were archived on boms rather than deleted: https://github.com/odoo/odoo/blob/4a5270218fe6fd7d30edb6d684b3340dc7423bab/addons/mrp/views/mrp_routing_views.xml#L53-L55 As such they would still be linked to an operation (but unrelated to the present values of the bom) and hence would fall into the condition of being unlinked from the MO. Since the bom operations are no longer archived there is no way to determine if an operation used to be linked to a bom and we therefore need to chose between deleting all operations unrelated to the present bom or to keep them all (when the MO has been confirmed). Community: https://github.com/odoo/odoo/pull/269747 opw-6285878 opw-6261738
This update resolves an issue where the Tax Return report in Odoo incorrectly displayed inflated amounts due to duplicate early-payment discount lines during batch reconciliation. The fix ensures accurate tax reporting by merging duplicate lines, preventing double-counting and maintaining correct tax totals. This improves the reliability of financial reporting.
Original PR description
Steps to reproduce 1. Create two customer invoices that share the same VAT tax, with a payment term granting an early payment discount. 2. Create one bank statement line whose amount equals the sum…
Steps to reproduce 1. Create two customer invoices that share the same VAT tax, with a payment term granting an early payment discount. 2. Create one bank statement line whose amount equals the sum of both invoices' discounted totals. 3. From the bank reconciliation widget, select both invoices and validate in a single batch reconciliation. 4. Open Accounting > Reporting > Tax Return, switch the variant to "Group by: Account > Tax". Issue The cash-discount expense row shows a Net base column equal to twice the real discount base. The Tax column is correct. The bank-statement reconciliation paths (set_line_bank_statement_line, set_batch_payment_bank_statement_line, _reconcile_payments) loop over each invoice and call _apply_early_payment_discount one invoice at a time. Each call writes one discount base line and one discount tax line on the resulting bank entry, so when two invoices share the same tax the bank entry ends up with two pairs carrying the same (account, partner, currency, tax_repartition_line_id, tax_ids). The SQL that feeds the tax report at https://github.com/odoo/odoo/blob/d7d0efd39a65bfb6fee307b661cd2523a6b8231d/addons/account/models/account_move_line_tax_details.py#L100 matches every base line of a tax with every tax line of that tax inside the same move. With two pairs sharing one tax that turns two rows into four, and SUM(base_amount) doubles. The Tax column does not double because the same SQL redistributes each tax line's recorded amount across its matched rows so the totals still add back to the original tax. The payment register flow does not have this problem because it calls _get_invoice_counterpart_amls_for_early_payment_discount once with every invoice, and that helper already collapses duplicates with the merge key at https://github.com/odoo/odoo/blob/f3b317310b84edb073009f7d15d7fec002f3ccf0/addons/account/models/account_move.py#L5082-L5093 opw-6199906
This update corrects a bug in the barcode scanning feature for stock receipts. Previously, the displayed quantity didn't accurately reflect the actual quantity received when using packaged items. The fix ensures that quantities are correctly converted to the stock move UoM, resolving the discrepancy between the barcode view and the stock move quantity.
Original PR description
**Steps to reproduce:** - Install `stock` and `purchase` modules - Enable `Units of Measure and Packages` and `Storage Locations` from setting - Create a storable product with vendor purchase UoM set…
**Steps to reproduce:** - Install `stock` and `purchase` modules - Enable `Units of Measure and Packages` and `Storage Locations` from setting - Create a storable product with vendor purchase UoM set to "Pack of 6" - Create and confirm a Purchase Order with quantity 6 Units - Open the generated receipt - Update a move line in Detailed Operations: - Quantity: 1 - UoM: Pack of 6 - Save and open the Barcode view using smart button. - Increase quantity using "+" button by 1. - Exit barcode view without validating and refresh the receipt **Issue:** After refresh, the stock move quantity becomes 1 instead of 6, while the move line correctly shows 1 Pack of 6. **Cause:** https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/static/src/components/main.js#L161-L162 - Exiting the barcode view triggers `__onExit()`, which forwards `reserved_uom_qty` and `qty_done` from move lines to `post_barcode_process()`. https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/static/src/models/barcode_picking_model.js#L1885-L1898 This `post_barcode_process()` function triggers `_truncate_overreserved_moves()` https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/models/stock_move.py#L56-L58 - During this flow, `_truncate_overreserved_moves()` updates the stock move quantity by taking the maximum of `qty_done` and `reserved_uom_qty`. However, it assigns this value directly to the move without converting it into the stock move UoM. - In this case, both values are 1 because the move line is UoM is "Pack of 6" Logically, 1 Pack corresponds to 6 units, but since the stock move UoM is in units, this conversion is skipped. As a result, the move quantity is incorrectly set to 1 instead of 6. https://github.com/odoo/enterprise/blob/2bfe0f32c0cec426fc7345ef716395146cc569ca/stock_barcode/models/stock_move.py#L52-L54 **Fix:** - Convert quantities coming from barcode processing into the stock move UoM before updating the move quantity, ensuring packaged UoM values are preserved correctly. ---- opw-5472598
This update resolves an error that prevented exporting the Deferred Revenue Report when annotations were added to invoices. The fix ensures the report can correctly handle invoices with deferred dates and annotations, improving report accuracy and functionality. This was caused by a missing variable initialization within the report generation process.
Original PR description
**Steps to reproduce:** * Install the **Accounting** module. * Unhide the **Deferred Start Date** and **Deferred End Date** (Deferred Date) fields on invoice lines. * Create and post a customer…
**Steps to reproduce:** * Install the **Accounting** module. * Unhide the **Deferred Start Date** and **Deferred End Date** (Deferred Date) fields on invoice lines. * Create and post a customer invoice with deferred dates. * Go to **Accounting → Review → Deferred Revenue Report**. * Add an annotation to a deferred revenue line by clicking the **message** icon next to the account. * Export the report in **XLSX** format. **Observed behavior:** * The export fails with a server error: `UnboundLocalError: cannot access local variable 'annotations_x_offset' where it is not associated with a value` **Cause:** * The variable `annotations_x_offset` is assigned inside the `for header_level_index, header_level in enumerate(options['column_headers'])` loop, which writes the "Annotations" column header for each header level. * The Deferred Revenue Report produces an empty `column_headers` list, so the loop body never executes and `annotations_x_offset` is never assigned. * When the code later tries to write annotation data for each report line, it references the unassigned variable, causing Python to raise `UnboundLocalError`. **Fix:** * Initialize `annotations_x_offset = None` before the header loop. * After writing all individual column headers (where `x_offset` already points to the first free column after all data columns), add a fallback: if `report_annotations` is set but `annotations_x_offset` is still `None`, assign it from the current `x_offset` and write the "Annotations" header. opw-6354473
This update resolves an issue where sharing voice transcript summaries via email created duplicate notifications for related records. The fix ensures that each lead receives only one email notification, improving the user experience and reducing unnecessary communications. This change was previously addressed in 19.2 and later versions.
Original PR description
Issue: Voice transcript 'share by email' button would get post the transcript summary to the chatters of all records of a given model. Steps: 1) install crm and ai 2) activate openai and gemini by…
Issue: Voice transcript 'share by email' button would get post the transcript summary to the chatters of all records of a given model. Steps: 1) install crm and ai 2) activate openai and gemini by saving the api keys inside settings. 3) create 2 crm leads in order a) lead 1 and lead 2 4) go into lead 1 and in the description then type in '/voice-transcription'. 5) Go into the 'transcription' section of the voice transcription 6) type something and save 7) then click 'start recording' 8) click 'stop recording' - it doesn't need to actually record 9) wait to process 10) click the 'share by email' button 11) check lead 2 for a message created (there shouldnt be one) 12) go back to lead 1 and click the 'share by email' button 13) check lead 2 again and a second message appears. that is becuase it makes a new mail.compose.message with res_ids of a list of multiple crm.lead.id (e This was fixed in 19.2+ with the pr https://github.com/odoo/enterprise/pull/115978. But it didnt make it in 19.0 and 19.1 Fix: default_res_ids: model?.config.resIds, -> default_res_ids: [model?.config.resId] take the single record id instead of the list res_ids opw-6285883
8 changes
Resolved issues and error corrections
Urban Piper point-of-sale orders are now fetched together with other server orders instead of through extra back-to-back requests. This reduces waiting time during order refreshes and lowers unnecessary server load without changing the user workflow.
Original PR description
Issue: pos_urban_piper overrode getServerOrders() to add a separate loadServerOrders() call for it's own orders before delegating to super, resulting in up to an additional sequential RPCs on every order fetch. Fix: Extract the base query domain into a new overridable getServerOrdersDomain() method. Each module overrides it to OR in its own domain via Domain.or([super.getServerOrdersDomain(), extraDomain]), so all orders are fetched in a single RPC call instead of three. Task-6284860
This update fixes an issue that prevented users from clearing the date field in the WIP Accounting Entry wizard, which was causing errors. The change ensures the wizard functions correctly when temporarily emptying the date field, improving user workflow and data accuracy.
Original PR description
Issue Before This PR: When clearing the Date field in the WIP Accounting Entry wizard, an error was raised during the re-computation of dependent fields. This prevented from temporarily emptying the…
Issue Before This PR: When clearing the Date field in the WIP Accounting Entry wizard, an error was raised during the re-computation of dependent fields. This prevented from temporarily emptying the date field while editing the wizard. Steps to Reproduce: - Open the list view of Manufacturing Orders. - Open the Post WIP Accounting Entry wizard by either: - Selecting one or more Manufacturing Orders and choosing Actions ,click Post WIP Accounting Entry - Or, opening a Manufacturing Order form and selecting Post WIP Accounting Entry from the Actions & Reports menu. - Clear the Date field. - Observe that an error is raised. Cause of the Issue: The compute methods _compute_reversal_date() and _compute_line_ids() assumed that wizard.date was always set. When the Date field was cleared, its value became False, but the compute logic still attempted to compare or use the date, resulting in an error. With This PR: The compute methods now verify that wizard.date is set before performing date-dependent computations. This prevents errors when the Date field is temporarily cleared, allowing the wizard to behave correctly during user input. Issue reference: https://github.com/odoo/odoo/issues/246547
This update fixes an issue where the Intrastat report was incorrectly cropping the bill name, preventing full visibility of key information like the hyphenated identifier. The fix adjusts a regex pattern to now correctly handle hyphen characters in bill names, ensuring accurate reporting and data display. This improves the clarity and usability of the Intrastat report.
Original PR description
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Intrastat" - Create a product with Intrastat info - Create a bill: * Product: [the created Intrastat product] * Intrastat Country: [any] * Intrastat Transport Mode: [any] - Confirm the bill - Make sure that the bill name contains a hyphen character (i.e. "-") For example, "BILL/2026-06/0001". Use the "Resequence" action from the bills list view if needed. - Go to "Accounting / Reporting / Audit Reports / Intrastat Report" - Expand the line to display the bill name **Issue:** The bill name is not fully displayed. It is cropped right before the hyphen character (i.e. BILL/2026). **Cause:** A regex is used to retrieve the bill name from the report line name, but it is only allowing "/" character. **Solution:** Just allow "-" character in addition. No other character is allowed to limit the risk of matching something that should not. opw-6299854
This update improves the speed of closing Point of Sale sessions, particularly when using 'Identify Customer' for bank payments. Previously, closing a session with many payments could take over 10 minutes. Now, the process is significantly faster – around 75 seconds – due to batch processing of payments and reconciliation.
Original PR description
Steps to reproduce ------------------ 1. On a bank payment method, enable "Identify Customer". 2. Create a lot of orders paid with this method (the client reporting the issue had 1700), and put a customer on each order. 3. Close the session. With "Identify Customer" enabled, closing the session creates one `account.payment` for each payment and posts it one by one, then reconciles each payment separately. With many payments this is slow and the close takes several minutes and the worker is stopped by its time limit, so we get the error "Cursor already closed". Now we create and post all these payments at once in a single batch, and reconcile the payments in one call too. Benchmark --------- These numbers come from closing a session that has 1700 orders paid with such a payment method, on a test database: - before: the close did not finish after more than 10 minutes. - after: the close takes around 75 seconds. opw-6242303
This update resolves a bug where recurring events synced from Google Calendar were sometimes duplicated, particularly when Google's 'UNTIL' date was set in UTC. The fix ensures Odoo correctly handles recurrence boundaries, preventing the creation of extra events that don't exist in Google Calendar. This ensures accurate event scheduling for users across different time zones.
Original PR description
When Google sends a recurrence with UNTIL in UTC (UNTIL=...Z), users in timezones behind UTC can get one extra occurrence on the boundary day. Google's UNTIL represents the last allowed start in UTC, but that UTC date fell into the previous local day. Because Odoo was comparing event start times as naive local datetimes against a cutoff derived from the wrong date, the boundary occurrence passed the check and was created. Steps to reproduce: 1. Set the user's timezone to a UTC-negative offset (e.g. America/Argentina/Buenos_Aires, UTC-3). 2. In Google Calendar, create a weekly recurring event (e.g. every Thursday at 12:00 local). 3. Edit the series with "This and following events" so the old series ends with UNTIL set to 02:59:59 UTC of the next day (= 23:59:59 local of the last valid occurrence day). 4. Sync with Odoo -> an extra event is created on the day after the last valid Thursday, which does not exist in Google Calendar. opw-6024835 Forward-Port-Of: odoo/odoo#265297
This update fixes a technical issue preventing the Gantt view from correctly displaying task progress for sales orders. The fix ensures that the system accurately calculates and displays planned hours when grouping tasks by sale order item, resolving a previous migration-related error.
Original PR description
### Steps to reproduce - Install `sale_timesheet_enterprise`. - Go to **Tasks → All Tasks**. - Switch to the **Gantt** view. - Group by **Sale Order Item** (`sale_line_id`). ### Issue A traceback is…
### Steps to reproduce - Install `sale_timesheet_enterprise`. - Go to **Tasks → All Tasks**. - Switch to the **Gantt** view. - Group by **Sale Order Item** (`sale_line_id`). ### Issue A traceback is raised when loading the Gantt view with group by `sale_line_id`: ```text ValueError: Invalid field 'planned_hours' on model 'project.task' for 'planned_hours:sum' ``` ### Root cause The Gantt progress bar computation for the `sale_line_id` grouping performs a `_read_group()` aggregation on the `planned_hours` field of `project.task`. However, `planned_hours` was renamed to `allocated_hours` during the saas-16.5 migration, so the former field no longer exists on `project.task`. As a result, the aggregation raises a `ValueError`. Migration reference: https://github.com/odoo/upgrade/blob/e638c6ce00d9d8936d034ad7130fef51565b9195/migrations/project/saas~16.5.1.2/pre-migrate.py#L10 Issued PR: https://github.com/odoo/enterprise/pull/49685 ### Fix Use `allocated_hours`, the renamed equivalent of `planned_hours`, when computing the Gantt progress bar. This restores the Gantt view when grouping tasks by **Sale Order Item** and prevents the traceback. Forward-Port-Of: odoo/enterprise#122297
This update resolves an issue where reloading the Odoo server could cause it to crash due to a race condition when handling `SIGHUP` signals. The fix ensures the server remains stable during reload operations, improving reliability and preventing service interruptions. This was triggered by multiple signals arriving simultaneously during a file change.
Original PR description
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP`…
### Summary When `dev_mode` includes `reload`, `ThreadedServer`'s FSWatcher reacts to a file change by sending the process a `SIGHUP` to trigger a phoenix restart. `signal_handler` turns `SIGHUP` into `KeyboardInterrupt`, which `ThreadedServer.run()`'s wait-loop catches. The catch is too narrow — a reload `SIGHUP` can kill the process through **three** windows that all sit outside the wait-loop's `try/except`, so the exception escapes `run()`/`main()`. Under Docker's default `restart: no`, PID 1 dies and the container stays down. ### The three windows 1. **Teardown duplicate (exit 130).** One file change can emit several FS events; the FSWatcher's `if not odoo.phoenix:` dedup races across threads and fires more than one `SIGHUP`. The first begins the phoenix teardown; the second lands during `stop()` / `watcher.stop()` / `_reexec()` and `KeyboardInterrupt` escapes. 2. **Exec-gap (exit 129).** `os.execve()` resets caught signal handlers to their default disposition (`SIGHUP` terminates) but preserves `SIG_IGN`; a `SIGHUP` arriving after the exec but before the re-exec'd process re-installs its handler kills the process outright. 3. **Startup (exit 130).** In the re-exec'd process, a `SIGHUP` anywhere in the startup section that precedes the wait-loop — `start()`, `preload_registries()` **and** `cron_spawn()` — escapes `run()`. ### Reproducer (deterministic) Boot a `ThreadedServer` (`--workers 0`) on any initialised db, then signal PID 1 a few times in quick succession: ```bash docker exec <container> sh -c 'i=0; while [ $i -lt 8 ]; do kill -HUP 1; sleep 0.1; i=$((i+1)); done' ``` Unpatched the process exits 130 or 129. Patched it stays up after one clean phoenix reload. Verified live on 17.0 and 18.0: stock `server.py` dies; the patched `server.py` survives sustained bursts (20/20 across repeated reload cycles on each version); `SIGINT`/`SIGTERM` still exit 0. ### Fix Minimal, in `signal_handler` + `run()` + `_reexec()`; `SIGINT`/`SIGTERM` untouched; one new instance attribute, no new module globals: - **Teardown duplicate:** ignore a `SIGHUP` once `quit_signals_received` is set (a restart/shutdown is already pending; the re-exec reloads fresh code). - **Startup:** a per-instance `in_preload` flag marks the entire startup section (`start()` + `preload_registries()` + `cron_spawn()`); a `SIGHUP` there sets the phoenix flag + counter and returns instead of raising, so the wait-loop exits right after startup and runs the normal restart. - **Exec-gap:** `signal.signal(signal.SIGHUP, signal.SIG_IGN)` just before `os.execve` so a `SIGHUP` in the gap is dropped rather than terminating the process. ### Related - #21209 (merged) — introduced the phoenix flag; did not guard these windows. - #206898 (merged), #207930 (open) — PreforkServer reload. ### CLA Covered by Codeforward B.V.'s corporate CLA; #269240 adds me to its contributor list (pending merge). Forward-Port-Of: odoo/odoo#269247
This update resolves a technical issue causing inconsistencies in the mod303 and mod390 tax reports for the Spanish (l10n_es) localization. The fix automatically adjusts tax grids to ensure accurate reporting, eliminating the need for manual adjustments. This improves the reliability of financial data for Spanish businesses.
Original PR description
### Steps to reproduce the issue: 1.Download Accounting and l10n_es 2. Switch to ES company 3. Make sure the reports mod303 and mod390 are empty for the month of May 2026 Tax 21% EU G (and 21% EU…
### Steps to reproduce the issue: 1.Download Accounting and l10n_es 2. Switch to ES company 3. Make sure the reports mod303 and mod390 are empty for the month of May 2026 Tax 21% EU G (and 21% EU IG): 3. Create a vendor bill with a line with the tax of 21% EU G in the month of May 2026 4. Create a refund (credit note) for that vendor bill in the month of May 2026 5. Look at the mod303 tax report for the month of May 2026 and notice that [27] in mod303 is not the same value as [34] in the mod390 report 6. Remove the +mod390[26] tag from the -100% refund line of the 21% EU G tax 7. Redo steps 2-4 and notice that [27] in the mod303 tax report is now the same value as [34] in the mod390 tax report, but also that [26] in the mod303 tax report is a different value now Tax 21% EU S: 1. Create a vendor bill with a line with the tax of 21% EU S in the month of May 2026 2. Create a refund for that vendor bill in the month of May 2026 3. Look at the mod303 tax report for the month of May 2026 and notice that [27] in mod303 is not the same value as [34] in the mod390 report. Also notice that [552] in mod390 is the same as [638] in mod390 4. Remove the +mod303[552] tag from the -100% refund line of the 21% EU S tax 5. Redo steps 2-4 and notice that [27] in the mod303 tax report is now the same value as [34] in the mod390 tax report, but also that [552] in mod390 is now different from [638] in mod390 ### Reason to introduce the fix: The report presented some discrepancies that can be fixed manually by changing the tax grid but it's still an error so it's better to also set the correct tax grids in the default taxes. opw-6277939 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
3 changes
Resolved issues and error corrections
This update ensures that lot numbers are consistently applied to incoming stock movements created during Point of Sale refunds. Previously, the system wasn't correctly reusing the original lot number when a refund was processed, leading to inconsistencies in inventory tracking. This fix maintains accurate lot number traceability for products, improving inventory management.
Original PR description
Steps: ---------- - Install point_of_sale. - Create a trackable product with a lot and add an on-hand quantity. - Open a PoS config with "Ship Later" enabled. - Place an order for the trackable product with a lot and ship later, then validate the delivery picking in Inventory. - Refund the previous order from PoS and ship later, and check the receipt in Inventory. Issue: --------- - The delivery picking correctly assigns a lot number, but the corresponding receipt created during the refund does not. Cause: --------- - The system was not reusing the existing lot number when the picking type was incoming. Fix: -------- - Ensure the existing lot number is assigned to incoming pickings created during refunds. task-5005122
This update resolves an issue where PDF invoices from Nilvera were being corrupted due to incorrect storage. The fix ensures PDFs are properly decoded and stored as valid files, preventing invoice processing errors. This improves the reliability of invoice generation and submission.
Original PR description
## Short fix summary: The PDF fetched from Nilvera comes back as a base64 string. It was stored verbatim in the attachment's `raw` field (no decoding), producing a corrupt PDF. Store it in `datas`…
## Short fix summary: The PDF fetched from Nilvera comes back as a base64 string. It was stored verbatim in the attachment's `raw` field (no decoding), producing a corrupt PDF. Store it in `datas` instead, which base64-decodes its input into a valid PDF. ### How it slipped in The mocked test for PDF fetching never mirrored the real API response: it returned raw bytes instead of the base64 string Nilvera actually sends, and asserted nothing about the stored file. Because the mock misrepresented the response, a later fix for a `binascii.Error` on Python 3.14 was applied in the wrong layer, switching the attachment field from `datas` to `raw`. That silenced the error but stored the base64 text undecoded, corrupting the PDF. The mock on the test will be corrected on Forward port of 18.0 onward. ### Related PRs - **#266718** — introduced the regression: switched the attachment field from `datas` to `raw` to silence a `binascii.Error` on Python 3.14, but stored the base64 text undecoded, corrupting the PDF. - **#246884** — added the mocked test suite that misrepresented the Nilvera `/pdf` response (raw bytes instead of a base64 string), which masked the bug and made the wrong fix in #266718 appear correct. task-6312640 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a formatting issue in the Hindi language setting within Odoo. It now correctly applies Indian-style number grouping (e.g., 1,54,75) for numerical displays, ensuring accurate representation of financial data for users in India. This improves clarity and consistency for Hindi-speaking users.
Original PR description
Currently the Hindi language used no number grouping at all. This commit sets the number grouping for Hindi to Indian style, like `1,54,75,317.70` e.g. [task-6320391](https://www.odoo.com/odoo/project.task/6320391)