Daily updates from Odoo
Tuesday, June 9, 2026
201 changes
26 changes
Resolved issues and error corrections
This update resolves a technical error that prevented users from successfully attaching PDF documents to invoices. The issue stemmed from a difference in how the system handles binary data versus base64-encoded data, specifically related to the Nilvera client's response. This change ensures invoices with PDFs can now be properly processed.
Original PR description
This commit resolves an error encountered when running on Python 3.14, which enforces stricter base64 validation. When adding a PDF to the invoice, the PDF is fetched using the Nilvera client. This client performs an HTTP request and returns a raw binary response, not a base64 representation. However, the Attachment interface handles raw binary data via the 'raw' field, whereas the 'datas' field strictly expects base64-encoded values. runbot-938173 Forward-Port-Of: odoo/odoo#268765 Forward-Port-Of: odoo/odoo#266718
This update corrects a bug that prevented signature requirement features from working correctly for shipments between US locations. The change adjusts the API request to accurately reflect the package-level nature of signature requirements for certain US deliveries, ensuring proper rate calculations and delivery confirmation. This resolves an error message preventing users from enabling signature requirements.
Original PR description
Issue ----- Enabling signature requirement blocks US -> US deliveries. Steps to reproduce ----- - Setup UPS - enable signature requirement - Set current company to US - Create a US Customer - Create…
Issue ----- Enabling signature requirement blocks US -> US deliveries. Steps to reproduce ----- - Setup UPS - enable signature requirement - Set current company to US - Create a US Customer - Create a product with some weight - Create a SO for the product - Add UPS delivery and try to get a rate > Error: "The requested accessory option is unavailable between the selected locations." Cause ----- Depending on the type of transfer, signature is requested at shipment or package level (see the "Delivery Confirmation Origin-Destination Pairs" category of the following link) https://developer.ups.com/api/reference/shipping/appendix1?loc=en_US US50 -> US50 & Canada -> Canada is package level Everything else is shipment level By default we use 'ShipmentServiceOptions_DeliveryConfirmation' for which 'DCISType' = 1 is the correct value. https://github.com/UPS-API/api-documentation/blob/b4064887ebcd9cd98085bc4cce088677c664473f/Shipping.yaml#L8902-L8911 For package level, we should use 'PackageServiceOptions_DeliveryConfirmation' for which 'DCISType' = 2 would be the expected value https://github.com/UPS-API/api-documentation/blob/b4064887ebcd9cd98085bc4cce088677c664473f/Shipping.yaml#L10410-L10421 ----- Ticket: opw-6173624 Forward-Port-Of: odoo/enterprise#117564
This update optimizes Odoo's styling process, specifically reducing the time it takes to recalculate styles in large tables like the Accounting Balances Sheets. By removing unnecessary selectors, the system now responds faster to window resizing, scrolling, and table sorting, leading to a smoother user experience.
Original PR description
Adapt selector to remove the :has value since it not needed to have the effect applied. This reduces work during the "Recalculate Style" phase (for example when hovering rows in large tables such as the Accounting > Balances Sheets). It lowers recalculation time during window resizes, heavy scrolling, and table sorting by preventing broad selector matches and limiting style checks to elements with the specific class. This commit is a follow up of https://github.com/odoo-dev/enterprise/commit/8aa63b3c726d825e68430bb0a64a54c1b58d6af7 Note: We also fixes the scss button variable not correctly overided Forward-Port-Of: odoo/enterprise#119521
This update strengthens data security by restricting access to sensitive financial information within expense reporting features. Previously, unauthorized users could view financial data. Now, only users with accounting or invoicing permissions can see key details, improving data protection and compliance.
Original PR description
Some financial data were visible to users with no access rights through the customer to reinvoice advanced search and analytic distribution search when creating an expense. This commit ensures that these fields in customer to reinvoice advanced search are invisible if the user doesn't have sales nor accounting nor invoicing access rights, it also modifies the debit/credit/balance columns in the analytic distr bution to be visible to users with accounting or invoicing access rights only. task-5993099 Forward-Port-Of: odoo/odoo#262986
This update fixes an issue where vendor bills imported from Poland's KSeF system were not correctly accounting for discounts applied to individual items. The update now properly parses the 'P_10' XML node, ensuring accurate bill data import and compliance with KSeF regulations. This improves the reliability of financial reporting.
Original PR description
When fetching vendor bills from KSeF, the XML node "P_10" is used to indicate a discount per unit on a line. This node is currently being ignored when parsing the file. Official documentation: https://ksef.podatki.gov.pl/media/gn2kt4gl/broszura-informacyjna-struktury-logicznej-e-faktury-fa-1-wersja-anglojezyczna.pdf opw-6235460 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268551 Forward-Port-Of: odoo/odoo#267235
This update changes how Odoo handles probe failures for serial devices like scales. Instead of generating error logs, a warning is now logged with detailed information. This prevents unnecessary alerts and improves the system's stability by reducing noise in the monitoring system.
Original PR description
Instead of logging an exception or an error on probe failure for serial devices, we now log a warning with stack info. This avoids spamming sentry with error logs that only are probe attempts. e.g. if the device plugged is a scale, we will probe for belgian + swedish blackbox first, causing two errors three times (as we retry 3x). see odoo/enterprise#119683 Forward-Port-Of: odoo/odoo#268796
This update adjusts the checksum associated with the scale certification process. Following a recent optimization of the scale driver to reduce error handling, this change ensures continued accurate certification verification. It's a routine maintenance update to maintain the integrity of our certification process.
Original PR description
As we updated the scale driver to reduce the amount of exception caught, we need to update the certification checksum. see odoo/odoo#268796 Forward-Port-Of: odoo/enterprise#119683
This update resolves a problem in the account module's testing process. Previously, leftover financial transactions interfered with test results, leading to inaccurate data. The fix ensures a clean test environment by canceling payments before removing transactions, preventing errors and improving test reliability.
Original PR description
The KPI provider test setup could leave some account moves behind when running with all modules and demo data installed. These leftover moves were then detected by subsequent test steps, causing incorrect numbers and test failures. This commit ensures the targeted moves are removed to provide an empty test environment. Payments need to be canceled first; otherwise unlinking the moves raises a ValidationError. [runbot-939456](https://runbot.odoo.com/odoo/error/939456) Forward-Port-Of: odoo/odoo#268151
This update introduces support for Belgian voluntary overtime within Odoo's payroll system. It allows for accurate tracking and reporting of overtime hours, including exemptions and standard rates, ensuring compliance with Belgian tax regulations (DMFA and 281.10 reporting).
Original PR description
Add support for Belgian voluntary overtime in payroll, DMFA, and 281.10 reporting. * Introduce dedicated work entry types for: * Voluntary overtime exempt from ONSS/precompte (DMFA service code 81) * Voluntary overtime subject to ONSS/precompte at 150% and 200% rates (DMFA service code 1, remuneration code 1) * Add salary rules and categories for voluntary overtime remuneration. * Enforce yearly thresholds through payroll parameters: * 240h for voluntary overtime exempt from ONSS * 120h for voluntary overtime subject to ONSS * Exclude voluntary overtime from employment bonus calculations and paid amount computation where required. * Include voluntary overtime remuneration in payroll calculations and DMFA declarations. * Add dedicated 281.10 reporting support for voluntary overtime exempt from ONSS using the reserved tax form fields. * Fix DMFA service hour computation and add payroll/DMFA test coverage. TaskID: 6275791 Forward-Port-Of: odoo/odoo#268313
This update introduces functionality to accurately calculate and report voluntary overtime hours for Belgian employees, aligning with local regulations. It includes new work entry types, salary rules, and reporting requirements for DMFA and 281.10 tax forms, ensuring compliance and accurate payroll processing.
Original PR description
Add support for Belgian voluntary overtime in payroll, DMFA, and 281.10 reporting. * Introduce dedicated work entry types for: * Voluntary overtime exempt from ONSS/precompte (DMFA service code 81) *…
Add support for Belgian voluntary overtime in payroll, DMFA, and 281.10 reporting. * Introduce dedicated work entry types for: * Voluntary overtime exempt from ONSS/precompte (DMFA service code 81) * Voluntary overtime subject to ONSS/precompte at 150% and 200% rates (DMFA service code 1, remuneration code 1) * Add salary rules and categories for voluntary overtime remuneration. * Enforce yearly thresholds through payroll parameters: * 240h for voluntary overtime exempt from ONSS * 120h for voluntary overtime subject to ONSS * Exclude voluntary overtime from employment bonus calculations and paid amount computation where required. * Include voluntary overtime remuneration in payroll calculations and DMFA declarations. * Add dedicated 281.10 reporting support for voluntary overtime exempt from ONSS using the reserved tax form fields. * Fix DMFA service hour computation and add payroll/DMFA test coverage. TaskID: 6275791 Forward-Port-Of: odoo/enterprise#119355
This update fixes a conflict in the Contracts module's menu ordering. Previously, other modules could disrupt the intended layout of the 'Configuration' menu. By adjusting the menu item's sequence, this change ensures the Contracts menu remains in its correct position, maintaining a consistent and predictable user experience.
Original PR description
## Description of the issue/feature this PR addresses The “Configuration” menu item defined by the *Contracts* module uses a very low sequence value, causing menu ordering conflicts when other…
## Description of the issue/feature this PR addresses The “Configuration” menu item defined by the *Contracts* module uses a very low sequence value, causing menu ordering conflicts when other modules (e.g. [OCA](https://github.com/OCA/partner-contact/pull/2202/files)) add menu items in the same section. This affects not only external modules but also internal ones that add menu items under *Contacts*. ## Current behavior before PR When other modules add new menu items to *Contacts*, the *Configuration* menu moves out of its intended last position, breaking Odoo’s default menu hierarchy. <img width="467" height="148" alt="Behavior before PR:" src="https://github.com/user-attachments/assets/4cb6e3bb-00c0-4636-87de-c51b572dc42c" /> ## Desired behavior after PR is merged The sequence of the *Configuration* menu item is adjusted so that it always remains last, aligning with Odoo’s default menu hierarchy and avoiding friction between modules. <img width="467" height="148" alt="Behavior after PR is merged" src="https://github.com/user-attachments/assets/314c2556-5f2b-403d-af8d-ab550bff41a9" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234909
This update resolves an issue where the year calculation was incorrect when weeks spanned across years, particularly at the end of 2026. The fix ensures consistent year and week number tracking, preventing unexpected behavior and maintaining accurate date calculations for reporting and scheduling.
Original PR description
### Description of the issue/feature this PR addresses: getLocalYearAndWeek is used to get the year and week number for a given date. When a week overlaps 2 years, the week number is taken based on…
### Description of the issue/feature this PR addresses: getLocalYearAndWeek is used to get the year and week number for a given date. When a week overlaps 2 years, the week number is taken based on the year where the week has most days. So if a week has 5 days in year Y and 2 in Y+1. The week is taken counting from Y (probably week 53). If a week has 3 days in Y and 4 in Y+1, then the week number is reset to 1. The year, however did not follow the same logic, and was taken as the year of the last day of the ISO week. ### Current behavior before PR: At the end of 2026, this will cause problems because the week number will run as: * 2026, week 52 (all days in 2026, OK) * 2027, week 53 (most days in 2026, last day in 2027, Not OK) * 2027, week 1 (all days in 2027, OK) ### Desired behavior after PR is merged: This commit aims to solve this issue by following the same logic for week number and year, so that the end of 2026 will go as: * 2026, week 52 (no changes) * 2026, week 53 (year is not incremented if week number is not reset) * 2027, week 1 (no changes, but year is incremented when week number is reset) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267871 Forward-Port-Of: odoo/odoo#267656
This update addresses a slow file preview issue when handling large files. Previously, users experienced a blank screen while a large file downloaded and rendered, leading to a frustrating experience. Now, a loading indicator is displayed during this process, providing immediate feedback and a smoother user experience.
Original PR description
When previewing a big file, the download might take long and the rendering might take even more time. The UI is blocked until the iframe is ready, but there is no feedback for the user. This commit adds some loading feedback until the iframe is rendered. Steps to reproduce: - Go to a Knowledge article - Upload a file with `/file` - Add a huge JSON file (~30MB) - Save - Click on the file icon => The preview opened but took ages to be displayed without giving any feedback to the user task-6014223 Forward-Port-Of: odoo/odoo#264136
This update resolves an issue where carousels would automatically cycle in edit mode, disrupting the page editing process. The fix pauses carousels when the edit mode is activated, ensuring a smoother and more reliable editing experience. This prevents unexpected focus changes and improves usability.
Original PR description
Commit [3ba3e45] paused carousels upon focus, and resumed it upon focusout. However, that behavior should be disabled in edit mode, as cycling is disabled (moving through the slides is only done manually). Otherwise, the carousel cycles and, after each slide, takes the focus, which makes editing the page a nightmare. [3ba3e45]: https://github.com/odoo/odoo/commit/3ba3e45b2ab995412e1a7ced2c46b9294dc353b8 task-6264462 Forward-Port-Of: odoo/odoo#268628 Forward-Port-Of: odoo/odoo#268046
This update resolves an issue where sponsor logos weren't loading correctly on exhibitor detail pages. The fix ensures the system uses the appropriate logo size (image_128) instead of a non-existent one, preventing placeholder images from appearing. This improves the visual presentation of our event exhibitor listings.
Original PR description
The sponsor logo was failing to load on the exhibitor detail page because the generic image widget was auto-generating a srcset with image_1920, a size that does not exist on event.sponsor (max: image_512). The browser would pick image_1920 from the srcset and receive a placeholder instead of the actual logo. Fixed by adding 'preview_image': 'image_128' to the t-options of the sponsor image widget, capping the srcset to existing image variants. there's another issue with the same fix: odoo/odoo@6bd2de2 related to: odoo/odoo@36e680f opw-6218587 Forward-Port-Of: odoo/odoo#264617
This update fixes a test that failed due to an assumption about the UoM feature being always enabled. The test now uses a reliable XMLID to identify items, ensuring stability across different Odoo builds (including single-app installations). This improves the reliability of our testing process.
Original PR description
Description of the issue this commit addresses: The test assumes uomDisplayName is always present and looks up Pack of 6 by name. In single_app builds, the UoM feature can be disabled, so the key is absent and a KeyError is raised. The name-based UoM search is also fragile. --- Desired behavior after this commit is merged: This commit stabilizes the test by using the Pack of 6 XMLID and by asserting uomDisplayName only when the UoM feature is enabled, while still verifying the quantity conversion logic for mixed UoMs. --- runbot-[939601](https://runbot.odoo.com/odoo/error/939601) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves issues with call records remaining incorrectly marked as "ongoing" due to a synchronization problem. It ensures call presence data is consistently updated during call creation and writing, and addresses a bug where demo calls incorrectly displayed user presence. This improves the reliability of call status information.
Original PR description
[FIX] voip: make sure any create/write on voip.call syncs user presence Commit [1] introduced a "in-call" presence icon. Before this commit, code updating call records had to call a specific function…
[FIX] voip: make sure any create/write on voip.call syncs user presence
Commit [1] introduced a "in-call" presence icon. Before this commit,
code updating call records had to call a specific function if user
presence potentially had to be changed after the record update. While
not hacking create/write to do that might be prettier, it is also
subject to mistakes and one was already made: demo data call record
creation did not update user presence properly. Commit [2] indeed
introduced calling/ongoing call demo data and the user presence was not
correct just after database initialization.
This commit fixes that by now potentially syncing in writes and always
syncing on create.
[FIX] voip: unstuck user call presence sooner in case of stuck calls
At the moment, the Odoo phone has a freshness system for call records
that appear still calling/ongoing for a strange duration. Indeed, there
are still cases where a call ended and we could not detect it. For
example, the user simply closing the tab where a call is ongoing (we try
to warn the user before he leaves but if agrees to leave anyway, the
call is just stopped when connexions are lost but the call record stays
marked as "ongoing"). In those cases, we have 2 things:
- A once-a-month cron checks all cases that are calling for more than
5 minutes or ongoing for more than 4 hours. It moves them to "ended
unexpectedly".
- The displayed status in views, shows "calling" / "ongoing" only if the
record is not older than 5 min / 4 hours. Otherwise it shows "ended
unexpectedly" already (as if the cron already did its job), despite
the record still having the "calling" / "ongoing" status.
It is weird and non-perfect but this allows to not have a "heavy" cron
job and consistent-enough call records display in views.
Of course, the long-term plan is to have more reliable call records
status (PBX, ...).
A new problem related to this appeared though. Since [1], a call icon
is used as the discuss presence icon in case the user is currently on a
call. The "currently on a call" data being transferred based on a field
"has_active_call" synchronized on call operations. Problem: in the case
mentioned above (call stuck in ongoing), that field will stay wrong for
a full month, showing the user as being on call. This commit makes it
so the check for active calls now considers fresh-enough calls (just
like the display in views does). It is only updated on a new call
operation though, so if an user has a stuck call, he will still be shown
as being on call until he starts/ends another call (or manually correct
the stuck call record).
Again, hopefully, stuck call records will be a thing of the past soon
enough so that issue will be minimized.
Note: this also uses `effective_start_date` instead of `start_date` to
check for stale calls, as it handles the potential no start_date while
ongoing that would stay stuck forever (that should not happen but,
better safe than sorry).
[FIX] voip: not consider incoming calling calls for presence status
Commit [1] introduced a "in-call" presence status. Commit [2], alongside
several fixes (e.g. parents of this commit and mentioned commit),
introduced new call demo data, including calling/ongoing calls:
- One incoming calling for Mitchell Admin
- One outgoing calling for Marc Demo
- One incoming ongoing for Marc Demo
- One outgoing ongoing for Marc Demo
Consequence: both Mitchell Admin and Marc Demo always have the "in-call"
presence icon, which might not be the best for demo. Still nice to test
VoIP but misleading for the rest.
In the end, we can have the best of both worlds: at the moment Mitchell
Admin only has an incoming calling call... and actually, that kind of
situation should not lead to being consider as "in-call". Calling
someone does, but receiving a call that we are potentially ignoring at
the moment does not.
This commit makes it so incoming calling calls are not considered for
presence anymore, at the same time thus making Mitchell Admin presence
not impacted by default VoIP demo data.
[1] - https://github.com/odoo/enterprise/commit/f1e0c41fa7b4f425e45303e5e912bf093c56480a
[2] - https://github.com/odoo/enterprise/commit/f16faa029220ca7152289180c4de78783bab03be
task-6239844A technical issue preventing users from submitting WhatsApp demo documents was resolved. The update added a necessary function to handle file size information during uploads, ensuring compatibility with the WhatsApp feature and other social media modules. This prevents errors and improves the reliability of the template submission process.
Original PR description
### Steps to reproduce: - Create a new WhatsApp account in Odoo - Select a pre-generated draft WhatsApp template (one that has a multimedia file) - Change the WhatsApp account of the template to the…
### Steps to reproduce: - Create a new WhatsApp account in Odoo - Select a pre-generated draft WhatsApp template (one that has a multimedia file) - Change the WhatsApp account of the template to the new account - Click on "Submit for Approval" to upload a demo document > TypeError: object of type 'LocalBinaryFile' has no len() ### Cause of Issue: When uploading attachments via the requests library, `len()` is called on the file object to determine the Content-Length header and to handle chunked transfer encoding. The `LocalBinaryFile` class was missing a that method. ### Fix: Added a `__len__()` method to the `LocalBinaryFile` class that returns `self.size`, which retrieves the file size from the `os.stat()` information already obtained during initialization. This allows the file size to be determined without loading the entire file into memory, maintaining the lazy-loading semantics of the class. ### Note: This bug also affects all social media modules which rely on uploading attachments with the requests library. opw-6272493
This update resolves an issue causing the website editor to crash when rendering a large number of custom website snippets. The fix ensures a clean template cache is used during compilation, preventing errors related to reusing outdated template data. This enhances the stability and reliability of the website editor for all users.
Original PR description
Steps to reproduce: - Ensure you're not in dev mode(`--dev xml` disabled) - Create ≈200 custom website snippets - Go into website edit mode - Traceback appears Because of the high number of snippets,…
Steps to reproduce: - Ensure you're not in dev mode(`--dev xml` disabled) - Create ≈200 custom website snippets - Go into website edit mode - Traceback appears Because of the high number of snippets, rendering the snippets templates exceeds the 1024-entry template cache limit. Earlier compiled templates are evicted from the LRU cache and may need to be processed a second time during the same render. The second compilation reuses the etree stored in the transaction preload cache. As this etree was already consumed by the first compilation, the resulting output can contain empty snippet wrappers and crash the website editor. This commit always copies preloaded etrees before compilation so the transaction cache retains a clean tree that can safely be processed again after an eviction. A fix was already done for the same error in [1], where it was only done for dev mode. opw-6230580 opw-6270833 opw-6276599 [1]: https://github.com/odoo/odoo/commit/f04a5cfee1a5c43824b04dec89712414b79e6cff Forward-Port-Of: odoo/odoo#268550
This update fixes an issue where the field service report was displaying incorrect information. The report now automatically uses the Planning Shift name and start date, ensuring accurate reporting. This change aligns with recent updates to the Odoo Enterprise system.
Original PR description
…port title - Removed the 't-if' condition containing 'doc.name', as 'doc.name' now refers to the Planning Shift name following the changes introduced in v19.2. - The report now displays 'start_datetime', which is automatically populated when a Planning Shift is created. - As a result, the 't-if' condition is no longer necessary. - This change aligns with the new behavior introduced in v19.2 and effectively replaces the Task name that was previously displayed before the report was migrated from 'project.task' to 'planning.slot'. Task-ID: 6284967 Forward-Port-Of: odoo/enterprise#119712
This update corrects a technical error that prevented email notifications from being sent correctly when scheduling tasks in planning slots. The previous code used an incorrect action name, which has now been corrected to align with standard Odoo practices. This ensures that email alerts function as expected.
Original PR description
the used action name for the Send Email action was false its supposed to be action_send and not action_send_email task: 6244506 Forward-Port-Of: odoo/enterprise#118334
This update resolves a crash that occurred when creating payslips for Belgian employees with overtime, specifically related to attendance-based contracts. The fix addresses a data structure mismatch that caused an error during payslip generation, ensuring accurate overtime calculations and preventing disruptions to payroll processing.
Original PR description
When creating a payslip for an employee in the Belgian localization with an hourly wage and an attendance-based work entry source contract, a traceback occurs if there is an attendance with overtime. This happens because the overridden `_preprocess_work_hours_data_split_half` method in `l10n_be_hr_payroll_attendance` attempts to unpack `work_entries` assuming it is a list of triplets, but it is passed as a `defaultdict` with composite keys instead. This data structure mismatch results in a `ValueError: not enough values to unpack (expected 3, got 2)`. Even if updated to handle the `defaultdict` structure, `_preprocess_work_hours_data_split_half` would improperly delete the overtime line hours without adding them back elsewhere (the code responsible for adding them back seems to have been removed). Since this function serves no purpose anymore, we omit the call to it. However, because `saas-19.2` is a stable version Task Id: 6253707 Forward-Port-Of: odoo/enterprise#118676
This update resolves an issue where portal users couldn't access photos attached to completed field service reports. The fix ensures that non-internal users can now view these images within the portal, improving the customer experience and providing more complete reporting. This aligns with our commitment to providing full visibility for our clients.
Original PR description
Photos were not accessible in the portal field service report for non-internal users. **Steps to reproduce** - Create a planning slot, set a portal user as the customer and mark the slot as "Completed". Add an image in the chatter. - Logged in with the customer's portal user account, access the field service report in the portal. The "Photos" section displays the name of the picture, but it is not possible to view it. <img width="888" height="320" alt="image" src="https://github.com/user-attachments/assets/523d1d1a-7c9c-4c9a-85f5-acd4df86d7ff" /> **Change** Similar to what is done in `project/controllers/portal.py` to give access to attachments to non-internal users from the portal, generate the necessary access tokens. opw-6236038 Forward-Port-Of: odoo/enterprise#118672
This update fixes an issue where users couldn't add Knowledge article notes to the 'Additional Notes' field on Manufacturing Orders. The fix changes a setting in the underlying product data to allow the system to recognize and use the 'Additional Notes' field for Knowledge integration, improving the ability to link relevant information.
Original PR description
Version: --------- - saas-19.2+ Steps to reproduce: ------------------- - Install `mrp` and `knowledge` - Open Knowledge and create an article - Add a clipboard block and write some text - Go to…
Version:
---------
- saas-19.2+
Steps to reproduce:
-------------------
- Install `mrp` and `knowledge`
- Open Knowledge and create an article
- Add a clipboard block and write some text
- Go to Manufacturing → Operations → Manufacturing Orders
- Create a new Manufacturing Order
- Open the `Miscellaneous` tab
- In the `Additional Notes` field, click the Knowledge icon(Top right corner)
- Search and open the created article
Issue:
------
The Knowledge article does not display the
`Use As Additional Notes` action.
Cause:
------
The Knowledge clipboard integration detects compatible editable HTML fields
from the active form view through `form_controller_patch.js`.
The detection first checks whether the field:
- is part of `KNOWLEDGE_RECORDED_FIELD_NAMES`,
- is an HTML field,
- and is writable.
```
The `note` field already satisfies the first condition: const KNOWLEDGE_RECORDED_FIELD_NAMES = [
'note',
'memo',
'description',
];
```
However, the detection logic also filters out readonly fields:
```py
fields[name].type === "html" &&
!fields[name].readonly
```
In `mrp.production`, the `note` field is computed `Html` field:
```py
note = fields.Html(
string="Additional Notes",
compute='_compute_note',
store=True,
)
```
Since computed fields are readonly by default unless explicitly marked
otherwise, Odoo exposes the field as readonly at the model level.
Even though the form view contains readonly Flase:
https://github.com/odoo/odoo/blob/9b9c72cc2c2ec0f7f5a74b39a11044b5f21f5d2e/addons/mrp/views/mrp_production_views.xml#L583
the Knowledge detection relies on the model field definition rather than
the view attribute. As a result, the `note` field is filtered out and
the clipboard action is never proposed.
Fix:
-----
Mark the computed `note` field as writable by setting
`readonly=False` in the model definition.
This allows the Knowledge clipboard detection to recognize the field as
a valid editable HTML target and restores the
`Use As Additional Notes` action in Manufacturing Orders.
---
opw-6209675
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#266668This update corrects a display issue related to Sunday formatting in the th_TH locale, which was impacted by a recent Chrome browser update (version 148). The change ensures consistent and accurate date and time formatting for Thai users, improving the user experience.
Original PR description
Chrome 148 changed the display format for Sundays in the th_TH locale. This commit modifies the test to expect either the full or abbreviated day name, depending on what the browser Intl API actually returns. Forward-Port-Of: odoo/enterprise#119708
This update resolves a problem where users accessing archived documents through certain methods (like widgets or direct URLs) would incorrectly display a 'not found' message. This fix ensures that archived documents are correctly opened, improving the user experience and preventing frustration. This was a follow-up to previous related tasks.
Original PR description
When a user tries to access an archived document via * a many2one widget * `/odoo/documents.document/<id>` * a discuss notification they end up in "All" with a toast specifying that the document was not found. Follow-up of Task-6068437 (follow up of Task-5386466). Task-6214488 Forward-Port-Of: odoo/enterprise#119565 Forward-Port-Of: odoo/enterprise#117229
15 changes
Resolved issues and error corrections
This update resolves an issue where Knowledge articles weren't appearing in the 'Additional Notes' field of Manufacturing Orders. The fix modifies a core Odoo setting to allow the 'note' field, used for these additional notes, to be treated as an editable HTML field, enabling seamless integration with the Knowledge clipboard feature.
Original PR description
Version: --------- - saas-19.2+ Steps to reproduce: ------------------- - Install `mrp` and `knowledge` - Open Knowledge and create an article - Add a clipboard block and write some text - Go to…
Version:
---------
- saas-19.2+
Steps to reproduce:
-------------------
- Install `mrp` and `knowledge`
- Open Knowledge and create an article
- Add a clipboard block and write some text
- Go to Manufacturing → Operations → Manufacturing Orders
- Create a new Manufacturing Order
- Open the `Miscellaneous` tab
- In the `Additional Notes` field, click the Knowledge icon(Top right corner)
- Search and open the created article
Issue:
------
The Knowledge article does not display the
`Use As Additional Notes` action.
Cause:
------
The Knowledge clipboard integration detects compatible editable HTML fields
from the active form view through `form_controller_patch.js`.
The detection first checks whether the field:
- is part of `KNOWLEDGE_RECORDED_FIELD_NAMES`,
- is an HTML field,
- and is writable.
```
The `note` field already satisfies the first condition: const KNOWLEDGE_RECORDED_FIELD_NAMES = [
'note',
'memo',
'description',
];
```
However, the detection logic also filters out readonly fields:
```py
fields[name].type === "html" &&
!fields[name].readonly
```
In `mrp.production`, the `note` field is computed `Html` field:
```py
note = fields.Html(
string="Additional Notes",
compute='_compute_note',
store=True,
)
```
Since computed fields are readonly by default unless explicitly marked
otherwise, Odoo exposes the field as readonly at the model level.
Even though the form view contains readonly Flase:
https://github.com/odoo/odoo/blob/9b9c72cc2c2ec0f7f5a74b39a11044b5f21f5d2e/addons/mrp/views/mrp_production_views.xml#L583
the Knowledge detection relies on the model field definition rather than
the view attribute. As a result, the `note` field is filtered out and
the clipboard action is never proposed.
Fix:
-----
Mark the computed `note` field as writable by setting
`readonly=False` in the model definition.
This allows the Knowledge clipboard detection to recognize the field as
a valid editable HTML target and restores the
`Use As Additional Notes` action in Manufacturing Orders.
---
opw-6209675
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update resolves a frustrating issue where carousels would automatically cycle while users were editing website pages. The fix prevents this cycling in edit mode, ensuring a smoother and more stable editing experience. This improvement simplifies the editing process and reduces user frustration.
Original PR description
Commit [3ba3e45] paused carousels upon focus, and resumed it upon focusout. However, that behavior should be disabled in edit mode, as cycling is disabled (moving through the slides is only done manually). Otherwise, the carousel cycles and, after each slide, takes the focus, which makes editing the page a nightmare. [3ba3e45]: https://github.com/odoo/odoo/commit/3ba3e45b2ab995412e1a7ced2c46b9294dc353b8 task-6264462 Forward-Port-Of: odoo/odoo#268628 Forward-Port-Of: odoo/odoo#268046
This update fixes a bug that allowed users to validate internal transfer barcodes without scanning the destination location. Previously, deleting a line would cause validation to succeed incorrectly. The fix ensures that validation is blocked until the destination location has been scanned, improving data accuracy and preventing incorrect transfer approvals.
Original PR description
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required.…
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required. ## Steps to produce: - Install the Inventory module - Go to Settings and enable Storage Locations. - Inventory > Configuration > Operation Types > Internal Transfers > Barcode App - Configure the Destination Location to require scanning after each product. - Create an Internal Transfer for Pedal Bin, demand 1. - Mark the transfer as To Do and open it in the Barcode app. - Add quantity using +1, then scan the barcode for the Pedal Bin(Barcode: 6016478556493). - Delete the newly added line and attempt to Validate. ## Observed Behavior: The system should prevent transfer validation when the destination location has not been scanned and display a notification to the user, similar to the behavior before user deleted the newly added line. ## Root cause: This issue occurs because when the delete button is pressed, the deleteLine function [1] removes the line, but the deleted line becomes the selected line due to [2] being triggered before the UI updates. As a result, the selected line is now undefined. Since the selected line is undefined, it fails to meet the condition at [3] during validation. This prevents notifications from being triggered and allows the transfer to be validated before the destination location has been scanned. [1]: https://github.com/odoo/enterprise/blob/3476d15bf8e75eb6530658dd623861b60963ab40/stock_barcode/static/src/models/barcode_model.js#L826-L836 [2] : https://github.com/odoo/enterprise/blob/327d4478128f33fb2e0c477533bd4983178abf17/stock_barcode/static/src/components/line.js#L129-L133 [3]: https://github.com/odoo/enterprise/blob/6ff158ca3a6d2d2b3d285a7f8317622844811688/stock_barcode/static/src/models/barcode_picking_model.js#L945-L948 ## Solution: We can prevent users from validating if any line has an unscanned destination location when destination-location scanning is mandatory after scanning each product. To enforce this behavior, we can track whether a line has been modified and whether a destination location has been scanned and applied to that line. This allows us to identify which lines still require destination location scanning before validation can proceed. However, line state information is currently discarded and recreated on every save. As a result, information about lines that were updated and already had their destination location scanned is lost. This may incorrectly require users to rescan the destination location, even though it was previously scanned. To address this, we preserve the destination-scanned and modified state by carrying it forward from existing lines to their corresponding newly created versions using a loop. This ensures that destination location scan status is retained and users are not asked to rescan unnecessarily. opw-6069614 Forward-Port-Of: odoo/enterprise#119499 Forward-Port-Of: odoo/enterprise#113618
This update resolves an issue where reverse charge GST calculations in the Singapore localization were incorrect due to inactive child tax settings. By activating the 'TXRC-TS' and 'TXRC-ESS' child taxes, the system now accurately calculates and reports GST, ensuring correct reporting in the Singapore GST returns. This improves the accuracy of financial reporting for Singapore-based businesses.
Original PR description
#### Description of the issue/feature this PR addresses: In the Singapore localization (l10n_sg), reverse charge is modelled as a group tax pairing a -9% SRRC child with a +9% TXRC child, so the GST…
#### Description of the issue/feature this PR addresses: In the Singapore localization (l10n_sg), reverse charge is modelled as a group tax pairing a -9% SRRC child with a +9% TXRC child, so the GST on a bill nets to zero while both legs are still reported in their respective GST return boxes. The child taxes "9% TXRC-TS" and "9% TXRC-ESS" shipped inactive, while their siblings "9% TXRC-N33" and "9% TXRC-RE" shipped active. Because children_tax_ids is a many2many onto account.tax (which has an active field), inactive children are filtered out of the group, so the groups "Reverse Charge - SRRC + TXRC-TS" and "Reverse Charge - SRRC + TXRC-ESS" only kept the -9% SRRC leg and computed a wrong GST amount, while leaving the +9% leg out of the GST return. #### Current behavior before PR: A vendor bill of S$10,000 taxed with "Reverse Charge - SRRC + TXRC-ESS" (or "+ TXRC-TS") shows 9% GST = -S$900.00 and a total of S$9,100.00 instead of net S$0.00 / S$10,000.00. The +9% TXRC leg never reaches Box 5 / Box 7 of the GST return. The sibling groups "+ TXRC-N33" and "+ TXRC-RE" are unaffected because their children are active. The only workaround is to manually activate the two child taxes. #### Desired behavior after PR is merged: The "9% TXRC-TS" and "9% TXRC-ESS" child taxes are active by default, so the group taxes aggregate both legs: a S$10,000 bill shows 9% GST = S$0.00 with a total of S$10,000.00, and both reverse charge legs land in their GST return boxes. New SG databases get this from the tax template; existing SG databases get the two taxes reactivated by a migration on upgrade. opw-6199248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267670
This update resolves an issue causing crashes in the website editor when rendering a large number of custom website snippets. The fix ensures a clean template cache is used during compilation, preventing errors related to outdated template data. This improves the overall stability and reliability of the website editor for users.
Original PR description
Steps to reproduce: - Ensure you're not in dev mode(`--dev xml` disabled) - Create ≈200 custom website snippets - Go into website edit mode - Traceback appears Because of the high number of snippets,…
Steps to reproduce: - Ensure you're not in dev mode(`--dev xml` disabled) - Create ≈200 custom website snippets - Go into website edit mode - Traceback appears Because of the high number of snippets, rendering the snippets templates exceeds the 1024-entry template cache limit. Earlier compiled templates are evicted from the LRU cache and may need to be processed a second time during the same render. The second compilation reuses the etree stored in the transaction preload cache. As this etree was already consumed by the first compilation, the resulting output can contain empty snippet wrappers and crash the website editor. This commit always copies preloaded etrees before compilation so the transaction cache retains a clean tree that can safely be processed again after an eviction. A fix was already done for the same error in [1], where it was only done for dev mode. opw-6230580 opw-6270833 opw-6276599 [1]: https://github.com/odoo/odoo/commit/f04a5cfee1a5c43824b04dec89712414b79e6cff Forward-Port-Of: odoo/odoo#268550
A recent issue prevented the correct generation of PDF reports when fillable forms were completely empty. This update fixes a technical error that caused a crash when attempting to create a PDF with no data, ensuring reports are always generated correctly. This improves the reliability of our PDF output.
Original PR description
Version: 19.0 Issue: - Uploading a fillable PDF with no filled-in values caused an error. Cause: - When all form fields are empty, nothing is drawn on the ReportLab overlay canvas, producing a 0-page PDF. - Calling getPage(0) on an empty page list raised an IndexError. Fix: - Skip the page merge when the overlay has no pages to avoid the IndexError on empty fillable forms. Forward-Port-Of: odoo/enterprise#119677
This update fixes an issue where credit limit warnings were incorrectly triggered when customers received bank payments. The system now accurately calculates outstanding balances by including bank payments, ensuring warnings only appear when limits are genuinely exceeded. This improves financial reporting and prevents unnecessary alerts for customers.
Original PR description
Before this fix: The credit limit warning calculation only considered credit notes but ignored outstanding bank payments when computing the partner's effective outstanding balance. For example, if a…
Before this fix: The credit limit warning calculation only considered credit notes but ignored outstanding bank payments when computing the partner's effective outstanding balance. For example, if a customer had a credit limit of 1,000 and an invoice of 2,000 was created, then a bank payment of 1,500 was received, the warning would still incorrectly appear showing the customer exceeded their limit (2,000 > 1,000), even though the actual outstanding amount was only 500. After this fix: The credit limit warning now properly includes outstanding bank payments in the calculation. Two cases are handled: - Bank payments received but not yet matched to any invoice, these are identified by their open suspense account entry and deducted from the partner's outstanding exposure. - Bank payments already matched to the invoice, the reconciled amount is read from the invoice's receivable line and deducted accordingly. So with this fix, after a 1,500 bank payment, the system correctly recognises the outstanding amount as 500 and does not show a warning since it is within the 1,000 credit limit. task-5427613 Forward-Port-Of: odoo/enterprise#119785 Forward-Port-Of: odoo/enterprise#118957
This update corrects a bug in the account reports module that caused the growth comparison percentage to fluctuate when users switched the order of reporting periods. The fix ensures the calculation remains consistent regardless of the period order, providing more reliable financial reporting. This improves the accuracy of growth analysis.
Original PR description
The feature had originally been implemnted at a time where the period_order couldn't be modified, and always corresponded to what we call 'descending' now. Because of that, we assumed the column at index 0 was always the most recent period ; which caused the growth comparison percentage to change when switching period order. Forward-Port-Of: odoo/enterprise#119280 Forward-Port-Of: odoo/enterprise#118835
This update resolves an issue where users were locked out of the documents list view after attempting to edit a row and clicking away without saving. The fix ensures the view correctly exits edit mode, allowing users to continue working without interruption. This improves user experience and prevents data loss.
Original PR description
Problem: When a user selects a row, attempts to edit a cell, and then clicks away without saving, the view becomes unusable. The selected row remains highlighted, and the system prevents the selection of other lines. The user is locked out until they click the "Save" or "Discard" buttons. Cause: The UI becomes stuck in edit mode. The `onGlobalClick` event handler within `documents_list_renderer` was missing the method call to exit edit mode. Solution: Updated `onGlobalClick` to correctly trigger the method to leave edit mode. task-6059836 Forward-Port-Of: odoo/enterprise#119594 Forward-Port-Of: odoo/enterprise#113000
This update corrects a bug where changes to the UrbanPiper provider state on the Ticket Screen weren't reflected correctly. The fix ensures that order filters update dynamically when the provider state is changed, preventing outdated information and improving the accuracy of order reviews. This improves the reliability of the UrbanPiper integration.
Original PR description
Steps to Reproduce ------------------------- - Install Point of Sale and configure UrbanPiper. - Open a POS session and select a provider state from the notification popup to review orders. - While on the Ticket Screen, select a different provider state to review other orders. Issue ------- - Orders are not updated according to the newly selected state. - Previously applied filters remain unchanged. Cause -------- - Since the user is already on the Ticket Screen, changing only the provider state does not trigger a re-render. - The page was already rendered with the old filters. Fix ---- - The Ticket Screen is first switched away and then re-rendered. - This forces the screen to reload with the updated state and filters. Task: 6079663 Forward-Port-Of: odoo/enterprise#119735 Forward-Port-Of: odoo/enterprise#104546
This update resolves an issue impacting payroll calculations for employees in Belgium using the 'eco' cheque system. The fix ensures accurate processing of these payments, addressing a previous error that caused incorrect amounts to be generated. This update improves the reliability of payroll processing for our Belgian customers.
This update resolves a problem with the calculation of Belgian eco vouchers (eco cheques) within the Odoo Enterprise system. The fix ensures accurate processing of these payments, addressing a previous error that could have resulted in incorrect financial reporting. This improves the reliability of payroll processing for businesses using the Belgian localization.
This update addresses a change in how Chrome 148 displays Sundays when using the th_TH locale. The code has been adjusted to accommodate the browser's updated Intl API, ensuring consistent and accurate date formatting for Thai users. This resolves a minor visual discrepancy.
Original PR description
Chrome 148 changed the display format for Sundays in the th_TH locale. This commit modifies the test to expect either the full or abbreviated day name, depending on what the browser Intl API actually returns. Forward-Port-Of: odoo/enterprise#119708
This update resolves a test failure caused by incorrectly formatted data being passed to the system. Specifically, raw PDF content was mistakenly treated as base64, leading to an error. This fix ensures that data is correctly encoded, improving test reliability.
Original PR description
This commit fixes an error when running the `test_employee_job_change` test on Python 3.14, which is stricter about base64 validation. Ultimately, the root issue was that raw PDF content was being passed when a base64 representation was actually expected (which is obviously invalid base64). runbot-938173 Forward-Port-Of: odoo/enterprise#119786 Forward-Port-Of: odoo/enterprise#118523
This update optimizes how Odoo identifies default suppliers for purchase orders, significantly speeding up the process. The change eliminates a performance bottleneck that caused delays in order processing, resulting in faster order fulfillment. The improvement was achieved by streamlining the supplier selection logic.
Original PR description
Currently, computing effective_vendor_id and supplier_id_placeholder presents N+1 query issues. Since every call to _get_default_rule() eventually triggers a _read_group() in _search_rule_for_warehouses(). However we can get rid of this entirely, since the subsequent call to _get_matching_supplier() with an empty values dict depends entirely on the product and not the rule. Benchmark web_search_read by effective_vendor_id on 12,000 orderpoints | |Query Count|Exec Time| |------|-----------|---------| |Before|15,519 |17.46s | |After |722 |3.21s | opw-6186351 Forward-Port-Of: odoo/odoo#268315
13 changes
Resolved issues and error corrections
This update fixes a problem where carousels would automatically cycle while editing website pages. This was causing frustration for users trying to make changes, as the carousel would repeatedly take focus and disrupt the editing process. The fix ensures carousels are paused when editing, allowing for smooth and focused page modifications.
Original PR description
Commit [3ba3e45] paused carousels upon focus, and resumed it upon focusout. However, that behavior should be disabled in edit mode, as cycling is disabled (moving through the slides is only done manually). Otherwise, the carousel cycles and, after each slide, takes the focus, which makes editing the page a nightmare. [3ba3e45]: https://github.com/odoo/odoo/commit/3ba3e45b2ab995412e1a7ced2c46b9294dc353b8 task-6264462 Forward-Port-Of: odoo/odoo#268628 Forward-Port-Of: odoo/odoo#268046
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed mailings linked to marketing automation, avoiding unintended spam and ensuring targeted email delivery. A user interface update and a new test were added for stability.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119597 Forward-Port-Of: odoo/enterprise#118759
This update fixes an error in the Singapore localization (l10n_sg) that caused incorrect GST calculations for reverse charge transactions. By activating inactive child tax rates, the system now accurately reflects the GST impact of these transactions, ensuring correct reporting in the GST return boxes. This ensures compliance with Singapore's tax regulations.
Original PR description
#### Description of the issue/feature this PR addresses: In the Singapore localization (l10n_sg), reverse charge is modelled as a group tax pairing a -9% SRRC child with a +9% TXRC child, so the GST…
#### Description of the issue/feature this PR addresses: In the Singapore localization (l10n_sg), reverse charge is modelled as a group tax pairing a -9% SRRC child with a +9% TXRC child, so the GST on a bill nets to zero while both legs are still reported in their respective GST return boxes. The child taxes "9% TXRC-TS" and "9% TXRC-ESS" shipped inactive, while their siblings "9% TXRC-N33" and "9% TXRC-RE" shipped active. Because children_tax_ids is a many2many onto account.tax (which has an active field), inactive children are filtered out of the group, so the groups "Reverse Charge - SRRC + TXRC-TS" and "Reverse Charge - SRRC + TXRC-ESS" only kept the -9% SRRC leg and computed a wrong GST amount, while leaving the +9% leg out of the GST return. #### Current behavior before PR: A vendor bill of S$10,000 taxed with "Reverse Charge - SRRC + TXRC-ESS" (or "+ TXRC-TS") shows 9% GST = -S$900.00 and a total of S$9,100.00 instead of net S$0.00 / S$10,000.00. The +9% TXRC leg never reaches Box 5 / Box 7 of the GST return. The sibling groups "+ TXRC-N33" and "+ TXRC-RE" are unaffected because their children are active. The only workaround is to manually activate the two child taxes. #### Desired behavior after PR is merged: The "9% TXRC-TS" and "9% TXRC-ESS" child taxes are active by default, so the group taxes aggregate both legs: a S$10,000 bill shows 9% GST = S$0.00 with a total of S$10,000.00, and both reverse charge legs land in their GST return boxes. New SG databases get this from the tax template; existing SG databases get the two taxes reactivated by a migration on upgrade. opw-6199248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267670
This update fixes a bug that prevented Point of Sale sessions from closing if draft orders were scheduled for the same day. The fix ensures that sessions can be properly closed regardless of the time of day, improving the user experience and preventing data inconsistencies. This change was made as part of a security-focused update.
Original PR description
A POS session could not be closed if there were draft orders planned for later the same day. The backend check was only filtering out orders with a date strictly in the future, ignoring the time part for same-day orders. task-id: 6000698 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251935
This update significantly speeds up the process of checking if a field can be deleted within website forms. Previously, this check took several minutes, causing delays. Now, it completes in just milliseconds by focusing only on the fields that actually need to be validated, improving user experience and system performance.
Original PR description
Summary ======= `_check_if_used_in_website_form`, the ondelete hook on `ir.model.fields` that guards against deleting a field referenced by a website form, performs poorly on realistic databases. It…
Summary
=======
`_check_if_used_in_website_form`, the ondelete hook on
`ir.model.fields` that guards against deleting a field referenced by
a website form, performs poorly on realistic databases. It can take
multiple minutes to validate a single field deletion, blocking user
actions such as removing a Studio field.
This commit restricts the scan to columns that can actually contain
website form markup, bringing the hook from multi-minute to
sub-second without any loss of coverage.
The Problem
===========
Deleting any `ir.model.fields` record triggers this validation hook,
which must ensure the field is not referenced inside any website
form. The implementation iterates every stored HTML column returned
by `website._get_html_fields()` and runs one case-insensitive
`ILIKE '%data-model_name="<model>"%'` search per column against
`<model>.<html_field>`, then parses each match with `lxml` and
validates it with XPath.
Two root issues cause the multi-minute cost:
- **Unbounded scan surface**: all stored HTML columns are scanned
(~95 on realistic databases), even though the vast majority of them
declare `sanitize=True` and `sanitize_form=True` (the defaults).
When both flags are True, `<form>` tags are stripped on write and
the column can never physically contain website form markup.
- **Per-column `ILIKE` cost**: `ILIKE` on large TEXT/JSONB columns
performs a sequential scan. A single large HTML column is enough
to make the hook run for several minutes on its own.
Improvements
============
- Scan only columns that can actually contain forms:
- `ir.ui.view.arch_db` , primary target; all website forms are
stored there.
- HTML fields whose sanitization either is disabled
(`sanitize=False`, e.g. `blog.post.content`,
`website.custom_code_head`) or explicitly allows forms
(`sanitize_form=False`, e.g.
`product.template.website_description`, `hr.job.description`,
`event.event.description`). Any other HTML field strips `<form>`
on write and will never contain a form.
- Batch searches: group the deleted fields by model once and emit a
single `OR`-domain search per candidate column, instead of one
search per (field, column) pair.
- Parse each returned record with `lxml` and validate with XPath
directly. The `ILIKE` domain already filters out non-matching rows
DB-side.
Benchmarks
==========
Profiled on a database containing ~95 stored HTML columns and ~5.2k
views. The hook was invoked read-only via
`field._check_if_used_in_website_form()` on a custom field.
| Metric | Before | After |
| :----------------------------- | ---------: | ---------: |
| Hook wall time | ~444 s | ~173 ms |
| HTML columns scanned | 95 | 5 |
| SQL queries issued | 96 | 6 |
Key results:
- Hook wall time reduced from multi-minute to sub-second
(~2,570× faster on the profiled database).
- Scan surface reduced from ~95 columns to a handful (1 +
the form-capable HTML fields installed on the database, typically
under 10).
opw-6086536
Forward-Port-Of: odoo/odoo#268666
Forward-Port-Of: odoo/odoo#259846This update resolves an issue where the 'Add to Cart' button wasn't functioning correctly for alternative products on the website. The fix ensures that users can now successfully add these alternative products to their cart, improving the shopping experience. This was caused by a problem with how the website dynamically renders product information.
Original PR description
Steps to reproduce: --- - Install `website_sale`. - Create a product and from the Sales tab, add alternative products, making sure all products are published on the website. - Open the main product…
Steps to reproduce: --- - Install `website_sale`. - Create a product and from the Sales tab, add alternative products, making sure all products are published on the website. - Open the main product on the website. - In the alternative products section, open the editor, click the `brush` icon under `card design`. - Under Actions > Buttons, click on the `cart` icon. - Save the changes and click the `Add to Cart` button on an alternative product. Issue: --- - Clicking the `Add to Cart` button on alternative products does nothing. Root cause: --- - At [1], the `AddToCart` interaction uses the selector `.oe_website_sale button[name="add_to_cart"]` to find and attach click handlers. When the dynamic snippet renders alternative products, `startInteractions` is called on the `.dynamic_snippet_template` div. It searches for the button inside that div, but at [2], no element wrapping the button has the `oe_website_sale` class in the rendered product card template. So the selector matches nothing, and no click handler is attached. Fix: --- - Add `oe_website_sale` to the `o_wsale_product_btn` wrapper div in the product card template so the button becomes a descendant of `.oe_website_sale` within the injected content, allowing the interaction to attach correctly. [1]https://github.com/odoo/odoo/blob/cbc446bfcaeeb4787cb512ddffbbeb2a154a6dde/addons/website_sale/static/src/interactions/add_to_cart.js#L5 [2]https://github.com/odoo/odoo/blob/cbc446bfcaeeb4787cb512ddffbbeb2a154a6dde/addons/website_sale/templates/snippets/product_snippet_template_data.xml#L95-L113 opw-6197375 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue causing the website editor to crash when rendering a large number of custom website snippets. The fix ensures a clean template cache is used during compilation, preventing errors related to re-processing previously consumed templates. This enhances the stability and reliability of the website editor for users creating and managing website content.
Original PR description
Steps to reproduce: - Ensure you're not in dev mode(`--dev xml` disabled) - Create ≈200 custom website snippets - Go into website edit mode - Traceback appears Because of the high number of snippets,…
Steps to reproduce: - Ensure you're not in dev mode(`--dev xml` disabled) - Create ≈200 custom website snippets - Go into website edit mode - Traceback appears Because of the high number of snippets, rendering the snippets templates exceeds the 1024-entry template cache limit. Earlier compiled templates are evicted from the LRU cache and may need to be processed a second time during the same render. The second compilation reuses the etree stored in the transaction preload cache. As this etree was already consumed by the first compilation, the resulting output can contain empty snippet wrappers and crash the website editor. This commit always copies preloaded etrees before compilation so the transaction cache retains a clean tree that can safely be processed again after an eviction. A fix was already done for the same error in [1], where it was only done for dev mode. opw-6230580 opw-6270833 opw-6276599 [1]: https://github.com/odoo/odoo/commit/f04a5cfee1a5c43824b04dec89712414b79e6cff Forward-Port-Of: odoo/odoo#268550
This update fixes a bug in the sale details report that prevented it from accurately reflecting discounts applied through loyalty programs. Previously, loyalty discounts weren't included in the report's totals and counts. This change ensures that all discounts, including those from loyalty programs, are correctly displayed in the report.
Original PR description
When generating the sale details report, the number of discounts would not include the discount given by a loyalty program. The same problem applies for the total discount amount. Steps to reproduce: ------------------- * Create a loyalty program that gives a 10% discount automatically. * Open the PoS and make an order that activate the loyalty program. * Close the session and open the sale details report for this session. > Observation: The discount number and total is 0 opw-6185554 Forward-Port-Of: odoo/odoo#267753
This update clarifies error messages when sending invoices via Peppol. Previously, users received a generic 'no VAT' error, which was confusing. Now, the system accurately identifies the missing Peppol VAT information (like Belgian Company Registry or French SIRET), guiding users to correct the required data.
Original PR description
When a user sends a move via Peppol to a customer that has a VAT number set but not a Peppol endpoint, we show the user a generic error ("no VAT").
This makes the user confused, as he already filled the VAT field of his customer, It's the Peppol VAT that is missing (it could be: Belgian Company Registry, France SIRET, ...etc, depending on the customer's country)
This PR makes the error message more accurate by showing exactly the missing required field.
task-5499707
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#264500
Forward-Port-Of: odoo/odoo#245915This update corrects a bug where products without lot/serial tracking incorrectly displayed expiration warnings. Previously, the system would still trigger expiration checks even after switching to quantity tracking. Now, products without tracking will automatically have expiration dates disabled, aligning with the intended use of expiration dates for tracked products.
Original PR description
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup…
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup since from saas-18.4 there is a line where if `ml.removal_date <= datetime.datetime.now()` the picking is expired. So, if the product previously met these conditions, it will still be able to enter this flow. And since this product doesn't use a lot_id it displays “You are going to deliver the product False, False which is expired or should at least be removed from stock” What should happen: When a product is not tracked, use_expiration_date should be False as expiration dates are intended to be managed through lots or serial numbers. Steps to reproduce 1. Enable Product Expiry. 2. Create a storable product with: - Tracking: By Lots - Use Expiration Date: enabled - Set a value greater than 0 for removal_time 3. Change the product tracking to By Quantity. 4. Create and validate a receipt for the product. Related Tickets: opw-6255673 Forward-Port-Of: odoo/odoo#268135
This update corrects a display issue related to Sunday formatting in the Thai (th_TH) locale, which was caused by a recent change in Chrome browser version 148. The fix ensures that the correct day name is consistently shown to users, maintaining accurate and appropriate localization.
Original PR description
Chrome 148 changed the display format for Sundays in the th_TH locale. This commit modifies the test to expect either the full or abbreviated day name, depending on what the browser Intl API actually returns. Forward-Port-Of: odoo/enterprise#119708
This update resolves a test failure caused by incorrectly sending raw PDF data instead of the expected base64 encoded format. The fix ensures that test data is properly formatted, preventing errors and maintaining the stability of the payroll accounting module.
Original PR description
This commit fixes an error when running the `test_employee_job_change` test on Python 3.14, which is stricter about base64 validation. Ultimately, the root issue was that raw PDF content was being passed when a base64 representation was actually expected (which is obviously invalid base64). runbot-938173 Forward-Port-Of: odoo/enterprise#119786 Forward-Port-Of: odoo/enterprise#118523
This update fixes a visual issue in the portal chatter interface where elements like the Follow/Unfollow button appeared misaligned due to excessive padding. The issue was caused by a duplicated padding class that has now been removed from both the website code and the underlying project code. This ensures a cleaner and more professional look for portal users.
Original PR description
**Steps to reproduce:** 1. Log in as a portal user. 2. Open a shared project and then open any task within it. 3. Observe the vertical spacing above the Follow/Unfollow button and the chatter…
**Steps to reproduce:** 1. Log in as a portal user. 2. Open a shared project and then open any task within it. 3. Observe the vertical spacing above the Follow/Unfollow button and the chatter component. **Issue:** The chatter UI has incorrect vertical spacing, causing elements like the Follow/Unfollow button to sit too far down and appear misaligned. **Cause:** The pt-2 padding class was hardcoded in two separate locations: 1. The compileChatter wrapper in project_sharing_form_compiler.js. 2. The portal.Chatter XML template. When combined this caused a double-padding effect forcing excessive space. **Fix:** Removed the hardcoded pt-2 class from both the JavaScript compiler wrapper and the core XML template. This eliminates the double-padding conflict. This resolves the alignment issue in Project Sharing and does not affect the layout or functionality of other portal components. task-4203362 Forward-Port-Of: odoo/odoo#268977 Forward-Port-Of: odoo/odoo#257490
4 changes
Resolved issues and error corrections
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed emails linked to marketing automation, reducing the risk of unintended spam and ensuring emails are delivered correctly through the campaign's defined rules. A user interface update also hides the 'Retry' button to avoid confusion.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119517 Forward-Port-Of: odoo/enterprise#118759
This update fixes an issue where planned dates were lost when converting projects to project templates. The change ensures that the original planned dates are retained when creating a template, streamlining project management workflows. This prevents data loss and maintains accurate scheduling.
Original PR description
Steps to reproduce: -------- - Open a project with a planned date set. - Create Template of that project. - Observe the created project template. Issue: ---------- The planned dates of the project are lost when converting the project into a template. Cause: ----- When we create a project template from a project, the project gets archived.Because a new project template record is created, and the start and expiration fields have copy=False, those dates are not being copied. Fix: ------- Explicitly pass the planned date when copying the project, so the project template keeps the original planned date. task-5872500
This update prevents empty ICS calendar files from being generated when publishing shifts. Previously, the system created an empty file when a matching time slot wasn't found, which caused issues with calendar integrations. Now, the ICS file is only generated when a valid shift slot is linked to an employee.
Original PR description
**Step:** - install planning - create a resource - create an open shift for a future date - in Gantt view: - publish shift and select the created resource - click “Publish & Send” - check the email and click “Add to Calendar” **Issue:** Currently, clicking “Add to Calendar” generates an empty ics file. **Reason:** During ics file generation, the planning token to find a slot using the planning date and employee. but, no matching slot is found, so the process returns an empty slot, resulting in an empty ics file. **Fix:** Generate the `planning_url_ics` only when a slot is linked with an employee. Otherwise, hide the “Add to Calendar” button and do not generate the ics file. Forward-Port-Of: odoo/enterprise#118978
This update resolves a test failure caused by incorrectly formatted data being passed to the system. Specifically, raw PDF content was mistakenly treated as base64, leading to an error. This fix ensures data is correctly encoded, maintaining the stability of the system.
Original PR description
This commit fixes an error when running the `test_employee_job_change` test on Python 3.14, which is stricter about base64 validation. Ultimately, the root issue was that raw PDF content was being passed when a base64 representation was actually expected (which is obviously invalid base64). runbot-938173 Forward-Port-Of: odoo/enterprise#118523
8 changes
Resolved issues and error corrections
This update resolves a test failure related to how data was being processed. The issue stemmed from incorrectly sending raw PDF content instead of the expected base64 encoded data, which caused a validation error. This ensures the testing process runs smoothly.
Original PR description
This commit fixes an error when running the `test_employee_job_change` test on Python 3.14, which is stricter about base64 validation. Ultimately, the root issue was that raw PDF content was being passed when a base64 representation was actually expected (which is obviously invalid base64). runbot-938173 Forward-Port-Of: odoo/enterprise#118523
This update fixes a visual glitch in the website builder's carousel feature. Previously, changing image sizes or adding borders could cause layout instability. Now, the carousel automatically adjusts its item heights to maintain a smooth, consistent appearance, regardless of content changes.
Original PR description
In a carousel snippet all carousel items keep a consistent height to prevent layout jitter when sliding. The height synchronization was broken in the `s_carousel` snippet when item dimensions were modified via border overlays (padding changes). The issue was caused by the resize event being triggered from a different jQuery instance than the one used to register the height synchronization listener, preventing the handler from being executed. Steps to reproduce (Border Overlay): 1. In the website builder, add the `s_carousel` snippet. 2. Drag the lower border overlay so that the height of an image increases. 3. Navigate through the carousel and observe height changes causing a jitter effect. Task: [5135520](https://www.odoo.com/odoo/project/974/tasks/5135520) Forward-Port-Of: odoo/odoo#266173 Forward-Port-Of: odoo/odoo#265549
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed emails linked to marketing automation, avoiding unintended spam and ensuring targeted email delivery. A user interface update also hides the 'Retry' button to prevent this action.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119517 Forward-Port-Of: odoo/enterprise#118759
This update prevents empty ICS calendar files from being generated when scheduling shifts. Previously, a lack of available slots resulted in an empty file when the 'Add to Calendar' button was clicked. Now, the ICS file is only created when a valid shift slot is linked to an employee.
Original PR description
**Step:** - install planning - create a resource - create an open shift for a future date - in Gantt view: - publish shift and select the created resource - click “Publish & Send” - check the email and click “Add to Calendar” **Issue:** Currently, clicking “Add to Calendar” generates an empty ics file. **Reason:** During ics file generation, the planning token to find a slot using the planning date and employee. but, no matching slot is found, so the process returns an empty slot, resulting in an empty ics file. **Fix:** Generate the `planning_url_ics` only when a slot is linked with an employee. Otherwise, hide the “Add to Calendar” button and do not generate the ics file. Forward-Port-Of: odoo/enterprise#118978
This update fixes an issue where undoing the auto-plan feature would reset a shift's allocated workload hours, leading to inaccurate reporting. The change ensures that allocated hours remain consistent after undoing, allowing for more reliable tracking of resource utilization. This improves the accuracy of shift planning and reporting.
Original PR description
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation…
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation triggers recomputation of allocated_hours, causing the shift to lose its original workload value. Current Behaviour --- When resource_id is set to False during undo: - _compute_allocated_hours is triggered (depends on resource_id) - _compute_allocated_percentage is triggered (depends on allocated_hours) - Both fields are recalculated, potentially changing allocated_hours from its pre-assignment value Expected Behaviour --- Undoing auto-plan should preserve allocated_hours at its pre-assignment value while allowing allocated_percentage to adapt to the new context (open slot vs assigned resource). Fix --- Use protecting context manager in action_rollback_auto_plan_ids to prevent allocated_hours from being recomputed when resource_id is removed. This allows allocated_percentage to recalculate naturally based on slot duration while keeping allocated_hours stable. task - 4952149 Forward-Port-Of: odoo/enterprise#102864
This update fixes an issue where invoices were incorrectly re-adding timesheets after a partial refund. The fix ensures that timesheets linked to previously fully invoiced orders are no longer considered when generating new invoices, preventing duplicate entries and maintaining accurate financial records. This improves invoice accuracy and reduces the risk of errors.
Original PR description
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create 2 lines for the services product in the SO, invoicing policy = based on timesheets - Create 2 timesheets for both SO items - Invoice the SO - Create a credit note for line 1 => only line 2 is invoiced and line 1 is now released - Back to the SO > create invoice again > Line 2 is added to the invoice again. ### Cause of Issue: When generating the new invoice, `_recompute_qty_to_invoice` identifies timesheets linked to refunded invoices. Because the original invoice was partially refunded, all timesheets attached to that invoice match the domain used to locate timesheets—even the timesheets for line 2, which wasn't refunded. ### Fix: Ensures that lines that have already been completely invoiced are safely ignored and not inadvertently re-added to subsequent invoices. opw-6217684 Forward-Port-Of: odoo/odoo#265840
This update resolves an issue where updating the website's extra menu caused the main site menu to unexpectedly close, leading to inconsistent user experience. The fix ensures the extra menu is closed before opening the site menu, guaranteeing a more reliable and predictable website navigation for users.
Original PR description
[FIX] website: close the extra menu before opening site menu Update of the extra menu item is done multiple times (cfr `afterFontsloading`). If the extra menu item and the site menu were already open before an update of the extra menu item, the result is a close of the site menu. This can lead to undeterministic error. To solve the problem, the extra menu dropdown is closed before opening the site menu. runbot-240955 Forward-Port-Of: odoo/odoo#268652 Forward-Port-Of: odoo/odoo#266376
This update fixes a bug where follow invitations weren't appearing in user inboxes unless a comment was added. The change ensures that the notification subject is always displayed, regardless of the comment content, resulting in more reliable and visible notifications for users receiving follow invitations. This improves the user experience and ensures timely updates.
Original PR description
Steps to reproduce: - Configure user A to receive inbox notifications. - As user B, invite user A to follow a record with Notify recipients enabled. - Open the inbox of user A. The Invitation to follow notification is not displayed in the inbox when no additional comment is provided. This happens because the notification body is empty unless extra comments are added. This commit fixes the issue by displaying only the subject when the body is empty. Task-[5485727](https://www.odoo.com/odoo/project/1519/tasks/5485727) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268583 Forward-Port-Of: odoo/odoo#244653
7 changes
Resolved issues and error corrections
This update resolves a test failure related to how data was being processed. Specifically, the system was incorrectly sending raw PDF content instead of a base64 encoded format, causing a validation error. This fix ensures data is in the correct format, allowing the test to run successfully.
Original PR description
This commit fixes an error when running the `test_employee_job_change` test on Python 3.14, which is stricter about base64 validation. Ultimately, the root issue was that raw PDF content was being passed when a base64 representation was actually expected (which is obviously invalid base64). runbot-938173 Forward-Port-Of: odoo/enterprise#118523
This update prevents unnecessary image data from being sent during menu synchronization, resulting in faster loading times and reduced data usage. Previously, placeholder images were included, even when no actual product image was defined. This change ensures only real images are transmitted, optimizing the user experience.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119482
This update corrects a problem where Fedex shipping labels were missing a crucial reference field (REF). This field is required by the Fedex API and ensures accurate tracking of shipments. The fix adds the necessary reference based on the order information, resolving this issue and improving shipping label accuracy.
Original PR description
Backport of bb4f8bf Original PR #116870 Forward-Port-Of: odoo/enterprise#118967 Forward-Port-Of: odoo/enterprise#117873
This update fixes an error in how Odoo validates invoice dates for Colombian DIAN reporting. The original system incorrectly interpreted dates due to timezone differences, leading to failed invoice submissions. This change ensures accurate date comparisons, resolving the issue and enabling proper DIAN document generation.
Original PR description
**Steps to reproduce:** * Install `l10n_co_edi` module with DEMO DIAN mode enabled. * Go to Accounting > Vendor > Bills and create a new bill. * Select any Colombian partner different from…
**Steps to reproduce:** * Install `l10n_co_edi` module with DEMO DIAN mode enabled. * Go to Accounting > Vendor > Bills and create a new bill. * Select any Colombian partner different from `Consumidor Final`. * Set the invoice date to 6 days in the past. * Select the DIAN Support Documents journal and a product with UNSPSC category. * Confirm the bill and click `Send Support Document to DIAN` after 5 PM Colombia time. **Observed behavior:** * An error is raised stating the issue date cannot be older than 6 days or more than 6 days in the future, even though the invoice date is within the allowed window in Colombia local time. **Cause:** * The date window validation in `_check_move_configuration` used `fields.Datetime.now()` which returns UTC time. Since Colombia is UTC-5, after 5 PM local time the UTC clock has already rolled over to the next calendar day, making a 6-day-old invoice appear 7 days old and failing the validation incorrectly. **Fix:** * Convert the current UTC datetime to the `America/Bogota` timezone and extract its local date before computing the allowed date window. * Compare directly against `move.invoice_date` (a `date` field) instead of using `fields.Datetime.to_datetime()`, keeping the comparison consistent as `date` vs `date`. opw-6011502 Forward-Port-Of: odoo/enterprise#115256
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed emails linked to marketing automation, reducing the risk of unintended spam and ensuring emails are delivered correctly through the campaign's defined rules.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119517 Forward-Port-Of: odoo/enterprise#118759
This update fixes an issue where undoing the auto-plan feature incorrectly reset shift workloads. Previously, the system recalculated allocated hours, leading to inaccurate workload values. Now, undoing the auto-plan preserves the original allocated hours while allowing the percentage to adjust, ensuring accurate shift planning.
Original PR description
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation…
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation triggers recomputation of allocated_hours, causing the shift to lose its original workload value. Current Behaviour --- When resource_id is set to False during undo: - _compute_allocated_hours is triggered (depends on resource_id) - _compute_allocated_percentage is triggered (depends on allocated_hours) - Both fields are recalculated, potentially changing allocated_hours from its pre-assignment value Expected Behaviour --- Undoing auto-plan should preserve allocated_hours at its pre-assignment value while allowing allocated_percentage to adapt to the new context (open slot vs assigned resource). Fix --- Use protecting context manager in action_rollback_auto_plan_ids to prevent allocated_hours from being recomputed when resource_id is removed. This allows allocated_percentage to recalculate naturally based on slot duration while keeping allocated_hours stable. task - 4952149 Forward-Port-Of: odoo/enterprise#102864
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The change prevents this by validating the product type and displaying a user-friendly error message, ensuring correct subscription setup and preventing unexpected behavior.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#119711 Forward-Port-Of: odoo/enterprise#107691
10 changes
Resolved issues and error corrections
This update corrects a bug that prevented signature requirement features from working correctly for US deliveries using UPS. The change adjusts the API request to match UPS's requirements for package-level deliveries, ensuring accurate rate calculations and delivery confirmation. This resolves an error message related to unavailable options.
Original PR description
Issue ----- Enabling signature requirement blocks US -> US deliveries. Steps to reproduce ----- - Setup UPS - enable signature requirement - Set current company to US - Create a US Customer - Create…
Issue ----- Enabling signature requirement blocks US -> US deliveries. Steps to reproduce ----- - Setup UPS - enable signature requirement - Set current company to US - Create a US Customer - Create a product with some weight - Create a SO for the product - Add UPS delivery and try to get a rate > Error: "The requested accessory option is unavailable between the selected locations." Cause ----- Depending on the type of transfer, signature is requested at shipment or package level (see the "Delivery Confirmation Origin-Destination Pairs" category of the following link) https://developer.ups.com/api/reference/shipping/appendix1?loc=en_US US50 -> US50 & Canada -> Canada is package level Everything else is shipment level By default we use 'ShipmentServiceOptions_DeliveryConfirmation' for which 'DCISType' = 1 is the correct value. https://github.com/UPS-API/api-documentation/blob/b4064887ebcd9cd98085bc4cce088677c664473f/Shipping.yaml#L8902-L8911 For package level, we should use 'PackageServiceOptions_DeliveryConfirmation' for which 'DCISType' = 2 would be the expected value https://github.com/UPS-API/api-documentation/blob/b4064887ebcd9cd98085bc4cce088677c664473f/Shipping.yaml#L10410-L10421 ----- Ticket: opw-6173624 Forward-Port-Of: odoo/enterprise#117564
This update resolves an issue where clicking on social media posts (Facebook, Instagram, YouTube) without comments would cause a system crash. The fix ensures that the comments dialog opens correctly for these posts, improving the user experience. It also aligns the appearance of comments counters for different social media types.
Original PR description
*=social_youtube,social_instagram,social_facebook,social_twitter, social_linkedin **How to reproduce:** - Open the Social Marketing feed. - Click a Facebook, Instagram, or YouTube stream post with no…
*=social_youtube,social_instagram,social_facebook,social_twitter, social_linkedin **How to reproduce:** - Open the Social Marketing feed. - Click a Facebook, Instagram, or YouTube stream post with no comments. **Issue:** - A traceback is raised because the click handler tries to call `click()` on a missing comments element. - The comments dialog does not open. **Cause:** - The kanban record click handler forwards clicks to `.o_social_comments`. - For some media, the comments counter is not rendered when the post has zero comments. - See: https://github.com/odoo/enterprise/commit/0293d3e839825a4333882e831960050070b02ba6 **Fix:** - Make the shared handler detect when the comments element is missing. - Delegate that case to media-specific handlers so Facebook, Instagram, and YouTube can open their comments dialog directly. - This commit also hides the X and LinkedIn comments counters when there are no comments, aligning them with the other social media cards. Task-6113089 Forward-Port-Of: odoo/enterprise#118006
This update fixes a potential error that could cause the system to crash when calculating rental availability for products with start and return dates. Specifically, it prevents issues arising from conflicting date ranges between the cart and the product page, ensuring accurate availability displays.
Original PR description
Preventing traceback on incompatible dates between the cart and the product page. How to reproduce: 1. Add to cart a product with periodicity Hours/Days with a start date = return date (e.g.: Projector). 2. Go to the product page of a product configured with Pickup > Return (e.g.: Premium Bike, Luxury Room) 3. Traceback, as we try to get the availabilities on a negative period. start date > end date, as both dates are equals and the time is set from the Pickup and Return fields. Forward-Port-Of: odoo/enterprise#119570 Forward-Port-Of: odoo/enterprise#119480
This update resolves a failed test within the Odoo payroll system. The change involved making payroll warning data updatable, ensuring the system's accuracy and stability. This fix prevents potential issues with payroll calculations and reporting.
Original PR description
In this commit, we fixed a failed test by setting some payroll warnings updatable. task-6247204
This update fixes an error in the calculation of a specific employee contribution (cotisation_812) related to end-of-collaboration payslips for Belgian employees. The previous calculation was incorrect, leading to inaccurate contribution amounts. This change ensures accurate reporting of these contributions, aligning with Belgian tax regulations.
Original PR description
* = l10n_be_hr_payroll, test_l10n_be_hr_payroll_account
STEP TO REPRODUCE:
------------------
1- Log into a belgium company
2- click on "End of collaboration" for an employee with a ANNUAL_SALARY_REVALUED equal to 52248.52
3- Generate the termination payslip
4- Check the cotisation_812 value:
this value will be equal at 1/2 * 1/100 * TERM_BASIC and not 1/100 * TERM_BASICThis update introduces support for calculating and reporting voluntary overtime hours in Belgium, aligning with local regulations. It includes new work entry types, salary rules, and reporting mechanisms for DMFA and 281.10 tax forms, ensuring accurate payroll and tax compliance.
Original PR description
Add support for Belgian voluntary overtime in payroll, DMFA, and 281.10 reporting. * Introduce dedicated work entry types for: * Voluntary overtime exempt from ONSS/precompte (DMFA service code 81) *…
Add support for Belgian voluntary overtime in payroll, DMFA, and 281.10 reporting. * Introduce dedicated work entry types for: * Voluntary overtime exempt from ONSS/precompte (DMFA service code 81) * Voluntary overtime subject to ONSS/precompte at 150% and 200% rates (DMFA service code 1, remuneration code 1) * Add salary rules and categories for voluntary overtime remuneration. * Enforce yearly thresholds through payroll parameters: * 240h for voluntary overtime exempt from ONSS * 120h for voluntary overtime subject to ONSS * Exclude voluntary overtime from employment bonus calculations and paid amount computation where required. * Include voluntary overtime remuneration in payroll calculations and DMFA declarations. * Add dedicated 281.10 reporting support for voluntary overtime exempt from ONSS using the reserved tax form fields. * Fix DMFA service hour computation and add payroll/DMFA test coverage. TaskID: 6275791 Forward-Port-Of: odoo/enterprise#119355
This update resolves an issue where partner names with '&' characters were being incorrectly formatted for SEPA bank file exports, leading to rejections. The fix ensures '&' is preserved in human-readable fields like partner names and addresses, aligning with banking standards and preventing errors.
Original PR description
Problem: The previous fix (replacing '&' with '+' in _replace_characters_SEPA) was applied globally, affecting both reference/identifier fields and human-readable fields such as <Nm> (partner name)…
Problem:
The previous fix (replacing '&' with '+' in _replace_characters_SEPA) was applied globally, affecting both reference/identifier fields and human-readable fields such as <Nm> (partner name) and address lines.
As a result, a partner named "test & test GMBH" was exported as:
<Nm>test + test GMBH</Nm>
instead of the expected:
<Nm>test & test GMBH</Nm>
This caused bank file rejections because '&' is the correct XML encoding of '&' and is accepted by banks in human-readable fields.
Root cause:
ISO 20022 / EPC217-08 distinguishes two categories of data elements:
- Reference/identifier fields (InstrId, Ustrd, etc.): must use the restricted basic Latin character set — '&' is not allowed and must be replaced with '+'.
- Human-readable fields (Nm, AdrLine, etc.): may contain the extended Latin character set — '&' is valid and must be preserved so lxml can XML-escape it to '&' in the output.
Fix:
Revert the global '&' → '+' replacement in _replace_characters_SEPA so that '&' is preserved for name/address fields. The replacement of '&' with '+' for reference/identifier fields is already handled explicitly at the call sites in _get_CdtTrfTxInf (InstrId, Ustrd) via .replace('&', '+') before sanitize_communication is called.
ref commit : https://github.com/odoo/enterprise/pull/110809/changes/9e698e4ac9fdf66189ff6712f90a144560a1b484
documentation https://www.europeanpaymentscouncil.eu/sites/default/files/KB/files/EPC217-08%20Draft%20Best%20Practices%20SEPA%20Requirements%20for%20Character%20Set%20v1.1.pdf:
Forward-Port-Of: odoo/enterprise#119640
Forward-Port-Of: odoo/enterprise#115409This update resolves an issue where the 'Sign Now' button wasn't appearing for internal users who were eligible to sign documents. The fix ensures the button is displayed correctly based on whether a signing order is in place, improving the user experience for internal signers.
Original PR description
Version: - saas-19.4 Steps to reproduce: - Create a sign request for an internal user. - Open the sign document from the Sign app. Issue: - The Sign Now button is not visible even when the current user is one of the signers. Cause: - The button visibility logic does not correctly check whether the current user is allowed to sign the document. Solution: - Show the Sign Now button when the current user is one of the pending signers and no signing order is configured. - If signing order is configured, show the button only when it is the current user's turn to sign. task-6267257
This update resolves a visual issue where the 'attendance-based' checkbox on employee payroll forms was missing its label and help text. The fix correctly positioned the field within the schedule group, ensuring it appears as intended for employees. This improves the usability of the payroll process.
Original PR description
[FIX] hr_work_entry_attendance: fix attendance_based checkbox Reproduction: Install hr_work_entry_attendance, employee form view, payroll tab, there is no label and help in the checkbox of attendance_based Bug cause: The field is added to the just after schedule group but indeed it should be added inside of the schedule group. Since it has not above group in view, it was not appearing properly. Solution: I put the field inside to the schedule group. task - 6284137
This update resolves a visual issue with the Frontdesk welcome screen, ensuring the privacy notice design adapts correctly to different content. This improves the user experience and maintains consistent branding within the Frontdesk module.
Original PR description
This PR fixes several visual issues caused the privacy notice design to be not tailored to any type of possible content. task-6022341
4 changes
Resolved issues and error corrections
This update optimizes the performance of account reports when hovering over tables with many columns. Previously, hovering caused significant lag and browser slowdowns. This change reduces the number of style calculations, resulting in a smoother and faster user experience.
This update streamlines spreadsheet document handling by disabling versioning for spreadsheets and frozen spreadsheets. This prevents unnecessary data duplication and improves performance, aligning with how spreadsheets manage their history through revisions. The change also hides the versioning action for these document types.
Original PR description
This PR consists of two commits. The first commit hides the Manage Versions action button for spreadsheet and frozen spreadsheet documents, since versioning is disabled for those records. The second commit is a backport of enterprise commit 0e319d0. It disables document versioning for spreadsheet and frozen spreadsheet documents, as spreadsheets already manage their history through spreadsheet revisions. This avoids creating unnecessary document history attachments when spreadsheet data is written or when a spreadsheet is copied. Task: [6236496](https://www.odoo.com/odoo/project/2328/tasks/6236496) Forward-Port-Of: odoo/enterprise#119619 Forward-Port-Of: odoo/enterprise#118484
This update corrects a display issue related to Sunday formatting in the Thai (th_TH) locale, which was impacted by a recent Chrome browser update. The change ensures consistent and accurate date display across different Chrome versions, maintaining a positive user experience for Thai-speaking customers.
Original PR description
Chrome 148 changed the display format for Sundays in the th_TH locale. This commit modifies the test to expect either the full or abbreviated day name, depending on what the browser Intl API actually returns. Forward-Port-Of: odoo/enterprise#119708
This update prevents empty ICS calendar files from being generated when scheduling shifts. Previously, clicking 'Add to Calendar' resulted in an unusable file. The fix ensures ICS files are only created when a valid shift slot is linked to a resource, improving the scheduling process.
Original PR description
**Step:** - install planning - create a resource - create an open shift for a future date - in Gantt view: - publish shift and select the created resource - click “Publish & Send” - check the email and click “Add to Calendar” **Issue:** Currently, clicking “Add to Calendar” generates an empty ics file. **Reason:** During ics file generation, the planning token to find a slot using the planning date and employee. but, no matching slot is found, so the process returns an empty slot, resulting in an empty ics file. **Fix:** Generate the `planning_url_ics` only when a slot is linked with an employee. Otherwise, hide the “Add to Calendar” button and do not generate the ics file. Forward-Port-Of: odoo/enterprise#118978
9 changes
Resolved issues and error corrections
This update corrects a problem where Fedex shipping labels were missing a crucial reference number (REF) field. This ensures accurate tracking and compliance with Fedex requirements. The fix adds the necessary reference information to the label, improving delivery visibility and preventing potential shipping delays.
Original PR description
Backport of bb4f8bf Original PR #116870 Forward-Port-Of: odoo/enterprise#118967 Forward-Port-Of: odoo/enterprise#117873
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The fix prevents this by validating the product setup, ensuring a subscription plan is present before allowing recurring product additions, improving order stability.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#107691
This update fixes an issue where superuser mode incorrectly identified kits from other companies, leading to inaccurate stock reporting. The change ensures that stock reports only consider kits within the current company, improving data accuracy and preventing incorrect inventory calculations. This resolves a bug impacting how kits are valued across multiple companies.
Original PR description
### Steps to Reproduce: 1. Have 2 companies (Company A and Company B) 2. Create a global product (visible in both companies) 3. in Company A, for the product BOM make it a normal type ("Manufacture…
### Steps to Reproduce:
1. Have 2 companies (Company A and Company B)
2. Create a global product (visible in both companies)
3. in Company A, for the product BOM make it a normal type ("Manufacture this product") with a couple components, each with 0 units in this company.
4. Set the product to have quantity 50 units in Company A
5. In Company B, for the product BOM make it a phantom type ("Kit") with one component, 100 units so there are 100 units of the product in Company B too.
6. Now only select Company A and on the product page, set the cost to any nonzero amount.
7. Go to Inventory > Reporting > Stock, and see how the quants are all 0. however, if you click into the product page, the on hand quantity SmartButton says 50
### Description of the issue/feature this PR addresses:
**Issue:** When stock valuation logic does a compute_value in superuser mode, the _bom_find method ignores multi-company record rules. This causes the search to find kits from other companies, leading to incorrect quantity computations.
**Solution:** Force the env to drop the superuser flag (su=False) specifically during the BoM search. This ensures the ORM applies standard ir.rule filters, and isolates BoM results to the current company context.
### Current behavior before PR:
In superuser mode, the BoM search is company-blind and returns the first matching kit found in the entire database. If a kit is found in a different company, the stock report incorrectly explodes the kits and looks for the components in the current company's warehouse.
### Desired behavior after PR is merged:
The BoM search should respect multi-company isolation so the system will only identify a product as a kit if a valid BoM exists within the user's active company or the global context.
opw-6170112
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update simplifies invoice sending by ensuring the 'By Peppol' method is only enabled by default for customers in designated countries (GR, IT, PL, PO, RO). This reduces user confusion and unnecessary notifications related to Peppol invoice sending in these regions.
Original PR description
Current behavior before PR: - If the customer has a valid Peppol endpoint, the 'By Peppol' invoice sending method is selected by default. - For countries like 'GR,' 'IT,' 'PL,' 'PO,' and 'RO,' peppol is not mandatory or not used for sending invoice. It brings noise and it bothers the users. Desired behavior after PR is merged: - The 'By Peppol' invoice sending method is set to true by default only for customers from PEPPOL_DEFAULT_COUNTRIES. Changes Implemented: - Moved the countries 'GR', 'IT, 'PL', 'PO', and 'RO' from PEPPOL_DEFAULT_COUNTRIES to PEPPOL_LIST. - Added condition to set 'By Peppol' invoice sending method to true when customer is from PEPPOL_DEFAULT_COUNTRIES. task-6072935 Forward-Port-Of: odoo/odoo#262402
This update significantly speeds up the process of adding and removing participants from marketing campaigns, particularly those with large numbers of users. The change optimizes the underlying code to reduce processing time from 51.71 seconds to just 0.652 seconds. This improvement enhances campaign management efficiency.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#117656
This update fixes an issue where users without HR access rights in the timesheet grid view were seeing a placeholder image instead of their avatar. The fix ensures that all users can correctly display their employee avatar within the timesheet grid, improving the user experience and visual consistency.
Original PR description
Steps to reproduce: ------------------- - Install the hr_timesheet module - Create a user without HR access rights - Create a timesheet - Log in with the above user - Open the kanban view Issue: ------- Instead of showing the employee's avatar, a placeholder image is displayed. Reason: ---------- The user does not have access to the hr.employee model. Fix: ----- In this commit, if the user does not have access to hr.employee,we fetch the image from the hr.employee.public model. task: 4461272 Forward-Port-Of: odoo/enterprise#83574
This update fixes a visual glitch where overlays (like dialog boxes) sometimes appeared twice on initial display. The change prevents unnecessary re-rendering of the overlay, resulting in a smoother and more reliable user experience. This improves the overall stability of the application.
Original PR description
Before this commit, sometimes an overlay such as Dialog could flicker and render twice on mount. This comes from implementation details for detecting whether the overlay comes from shadow DOM or…
Before this commit, sometimes an overlay such as Dialog could flicker and render twice on mount. This comes from implementation details for detecting whether the overlay comes from shadow DOM or website, to determine which overlay container should decide to display the overlay [1]. The code relies on presence of the root id in the DOM and overlay container was relying on presence of `ref.el` to get the root id from DOM. This was motivated by `isVisible(overlay)` whose computation was also relying on the ref [2] but this has the drawback that `ref.el` was sometimes not yet available immediately on 1st rendering. Solution of [1] was to re-renderer whenever `ref.el` is set, but another solution that prevents a re-render is to have the root id in the `env`. This commit changes the solution of [1] by instead `rootId` in the `env`. The new solution has the benefit to not require a re-render of the overlay container, which prevents undesirable flickers that may happen on mounting an overlay for the 1st time. [1]: https://github.com/odoo/odoo/pull/169264 [2]: https://github.com/odoo/odoo/pull/154349
This update resolves an issue where both failed and passed units were incorrectly moved to the failure location within the Quality Control process. The fix ensures that the destination of moved goods is accurately determined based on remaining demand, preventing unintended misplacement of inventory. This improves the reliability of quality checks and reduces potential stock discrepancies.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ------------------- 1. Install *quality_control* module. 2. Go to *Settings* and enable *Storage Locations*. 3. Open Quality module go to the Quality…
Version:
----------
- 18.0+
Steps to reproduce:
-------------------
1. Install *quality_control* module.
2. Go to *Settings* and enable *Storage Locations*.
3. Open Quality module go to the Quality control -> Quality points
4. Create a *Quality Point* with:
* *Product* set.
* *Control per* set to *Quantity*.
* *Operation* set to *Receipts*.
* *Failure Location* set to *WH/Stock/Shelf1*.
5. Create a *Receipt* with demand of *2 units* for the product used in QP.
6. Mark the quality check as *To Do*.
7. Update the *Done Quantity* to *1*.
8. Open the quality check and click *Fail*.
9. Update the *Done Quantity* back to *2* and save.
10. Open the quality check again, click *Pass*, and validate the receipt.
11. Open the *Detailed Operations* to inspect move lines.
Issue:
------
* Both units (failed and passed) are moved to the *failure location*.
Cause:
------
When a user fails a move line via the QC wizard, the flow is:
do_fail() → show_failure_message() → confirm_fail()
→ check._move_to_failure_location(failure_location_id, failed_qty)
Inside `_move_to_failure_location`, when `failed_qty == move_line.quantity`,
the condition:
https://github.com/odoo/enterprise/blob/a33f580455a54a81d89a848f7b493d9dcc9ba2b2/quality_control/models/quality.py#L458
e.g. 1 == 1
was True even when `move.product_uom_qty = 2` (demand still 2). It only
compared the done quantities, ignoring that unfulfilled demand remained.
As a result, `move.location_dest_id` was set to the failure location.
Later, when the user increases the quantity from 1 to 2 on the move form,
the flow is:
_set_quantity → process_increase → _set_quantity_done → _prepare_move_line_vals
In `_prepare_move_line_vals` :
'location_dest_id': self.location_dest_id.id,
https://github.com/odoo/odoo/blob/47bf284e1e9d8be0d4255418e0a3f67c74fa5114/addons/stock/models/stock_move.py#L1688
The new move line inherits `move.location_dest_id` directly, which at this
point is already the failure location.
When the user then calls `do_pass()` on the second unit, `do_pass()` only
writes `quality_state = 'pass'` and never touches `location_dest_id`. So
the second (passed) move line silently retains the failure location.
Solution:
---------
Add the guard `move.product_uom_qty <= move_line.quantity` to the condition
so the entire move's destination is only redirected when there is genuinely
no remaining unfulfilled demand:
When demand > done qty, the else-branch runs instead: it reduces the
original move's demand and creates a new separate move pointing to the
failure location, leaving the original move's `location_dest_id` pointing
to stock. Any subsequent move lines created on the original move therefore
correctly inherit the stock destination.
---
opw-6080871This update resolves a bug where importing XML bills with identical filenames resulted in the creation of multiple vendor bills. The fix ensures attachments are correctly linked to the appropriate accounting records, preventing duplicate bill generation. This improves data accuracy and simplifies invoice processing.
Original PR description
Fixup of https://github.com/odoo-dev/odoo/commit/3fc85b6ed7936956abbaf8e8364bb2b288cbe289 Issue 1 - Import XML bill into documents app - Create vendor bill from the document Issue: Only the main attachment would be found in the created bill opw-6267888 Issue 2 - From the accounting app import XML bill containing two identically named documents Issue: Two bills were created opw-6231265 Forward-Port-Of: odoo/odoo#268310
4 changes
Resolved issues and error corrections
This update resolves a technical issue that caused the restaurant order tour to fail. The fix ensures the system waits for order requests to fully complete before proceeding, preventing duplicate requests and improving the reliability of the test. This ensures a smoother experience for users placing restaurant orders.
Original PR description
The tour could fail because `sendOrderInPreparationUpdateLastChange` is asynchronous when sending the order to the kitchen. The test was continuing to the next steps before the request was fully resolved, which could lead to sending the order again while the previous call was still in progress. This commit updates the tour to explicitly wait for the async call to complete before continuing, by adding a delay step after clicking the order button. This prevents race conditions during the test. --- Runbot Error: https://runbot.odoo.com/odoo/runbot.build.error/181846
This update corrects a bug in the journal report that prevented accurate display of tax grids when multiple countries were selected. Previously, the report layout was broken, and country options were missing when using more than two tax countries. This ensures accurate reporting across various international business scenarios.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore.
This update resolves an issue where SEPA QR codes were occasionally displaying incorrect decimal places due to floating-point calculations in Odoo. The fix ensures the QR code amount accurately reflects the currency's precision, improving payment accuracy and preventing potential errors during scanning. This impacts vendor bill payments.
Original PR description
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of…
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of respecting the currency's expected precision. This occurs because the `amount` variable in `_get_qr_vals` was being converted directly using `str(amount)`. Due to Python's floating-point arithmetic, the float value in memory can contain decimal drift. Directly casting it to a string exposes this drift in the payload. This commit resolves the issue by replacing `str(amount)` with `float_repr(amount, currency.decimal_places)`. This safely bypasses the float representation issue, ensuring the string strictly respects the currency's configured decimal precision before being injected into the QR code. opw-5504258 **Steps to reproduce:** - Select company “My Belgian Company” - Create a 23% purchase tax - Create vendor bill - Select Vendor “BE Company CoA” - Choose any single product, change price to 37.18 and choose the 23% tax. The Untaxed Amount should be 37.18, VAT tax should be 8.55, and Total should be 45.73 - Confirm > Register Payment > scan QR code. EUR45.730000000000004 should show **Current behavior before PR:** - When generating a SEPA QR code for a payment, the embedded amount can contain excess decimal places due to floating-point drift. **Desired behavior after PR is merged:** - The SEPA QR code is generated with the correct number of decimal places.
This update significantly speeds up the process of grouping email messages, particularly when dealing with large volumes of data. The previous method was inefficient, causing slowdowns. This change optimizes the code to process messages much faster, improving overall system performance.
Original PR description
## The Problem When grouping messages, the code was accumulating recordsets using the `|=` union operator inside a loop. Since each union call internally builds an `OrderedSet` over all previously…
## The Problem When grouping messages, the code was accumulating recordsets using the `|=` union operator inside a loop. Since each union call internally builds an `OrderedSet` over all previously accumulated IDs, the performance degraded quadratically relative to the number of document records. This caused bottlenecks on databases with large message volumes. ## The Solution * Replaced the `|=` recordset accumulation with a plain Python dictionary of ordered sets to store IDs per operation, while keeping same behavior. * Deferred the `browse()` call until after the loop is complete. * Reduced the overall complexity from **$O(N^2)$** to **$O(N)$**. --- ## Benchmarks *Tested on a customer database grouping by "Created By" and "Created On":* | Record Count | Before | After | Improvement | | :--- | :--- | :--- | :--- | | **300k records** | 83.00s | **1.00s** | **-99%** | | **30k records** | 0.60s | 0.25s | (Minor) | **Note:** The performance gains become exponentially more significant as the record count grows. **OPW-6123758**