Tuesday, March 24, 2026
20 changes · 19.0
New functionality added to Odoo
This change adds a shared set of Claude assistant commands, agents, and skills to the repository. It is intended to help development teams run audits, reviews, documentation syncs, and other support workflows more consistently, without changing Odoo business features.
Original PR description
## Zusammenfassung - `.claude-agents/` Submodul eingebunden (claude-agents inkl. claude-skills) - `.claude/commands/` — Symlinks zu allen Slash-Commands (/repo-audit, /live-audit, /use-skill, etc.) - `.claude/agents/` — Symlinks zu allen Sub-Agenten - `.claude/skills/` — Symlink zu 13 Skills (odoo/, security/, ubuntu/, macos/) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Enhancements to existing features
Odoo now saves more useful Chrome debug logs when browser-based tests run, making it easier to understand failures such as crashed tabs or timeouts. This should help engineering teams diagnose test issues faster while reducing confusion from irrelevant Chrome error output.
Original PR description
Followup and partial revert of #232612: turns out chrome's stderr is worthless at best and confusing at worst (because it logs a bunch of dbus errors which don't actually matter), however chrome…
Followup and partial revert of #232612: turns out chrome's stderr is worthless at best and confusing at worst (because it logs a bunch of dbus errors which don't actually matter), however chrome turns out to have pretty extensive debug logging facilities which are somewhat valuable: https://www.chromium.org/for-testers/enable-logging/
For instance if the oomkiller decides to nuke a chrome tab (example selected for no reason whatsoever), the debug log will have an entry along the lines of
[...:WARNING::chrome/browser/ui/sad_tab.cc:256] Tab Killed: http://127.0.0.1:8069/
which is a much more helpful hint than just being told a test timed out (to say nothing of being told that chrome was not able to do dbus stuff when we never asked for that).
Because it can be useful for all sort of debugging, this log is saved not just when chrome fails to start, but also when a Chrome completes, successfully or unsucessfully (in the latter case it's logged as RUNBOT to be available from the runbot UI).
The chrome logging facilities are controlled by a new envvar `ODOO_BROWSER_LOG_VERBOSITY`, it can be set to `-1` to disable logging, or a strictly positive integer for ever increasing amounts of logging. At `1` chrome will log every network request it attempts which can be useful for debugging some races but is already extremely noisy.
Forward-Port-Of: odoo/odoo#255393
Forward-Port-Of: odoo/odoo#255054Resolved issues and error corrections
Marking a CRM lead as won no longer triggers an error when the lead has no valid stage assigned. This prevents a rare but disruptive sales workflow failure, especially in customized CRM setups where default stages may have been removed.
Original PR description
An error occurs when marking a lead as Won while it does not belong to any valid CRM stage. **Steps to Reproduce:** 1. Install **CRM** module. 2. Create a new user. 3. Delete all the default crm stages. 4. Create a lead **older than 31 days** with no stage assigned (change system date if required). 5. Assign the new user as **Salesperson** and set **Expected Revenue = 0**. 6. Mark the lead as **Won**. **Error:** `ValueError - invalid literal for int() with base 10: 'false'` **Cause:** When a lead does not belong to a valid stage, the `stage_id` become False. When it tries to cast `stage_id` to an integer, an error will be raised. **Fix:** This commit ensures only valid numerical stage ids are processed. sentry-7193424787
Inventory valuation reports for past dates now handle return transactions with no valued quantity safely. This prevents a calculation error from interrupting reporting and lets the valuation continue with no added value from that return.
Original PR description
When computing inventory valuation for a past date, AVCO valuation may re-evaluate return moves through `_get_value_from_returns()`. That method values the return from the original outbound move and assumes that the original move always has a non-zero valued quantity. However, `_get_valued_qty()` can be zero, for instance when the original move has no valued move lines. In that case, the report crashes with a `ZeroDivisionError` instead of continuing safely. This change guards against a zero valued quantity and falls back to an empty valuation contribution. opw-5944584 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Emails sent through invoice Send & Print now keep the Reply-To address configured on the email template. This ensures customer replies go to the intended mailbox instead of being redirected to the system default or sender address.
Original PR description
Steps to reproduce: 1. Go to an Email Template (e.g., 'Invoice: Send by email') and set a specific 'Reply-To' address. 2. Open a posted Invoice and click the 'Send & Print' button. 3. Ensure the…
Steps to reproduce: 1. Go to an Email Template (e.g., 'Invoice: Send by email') and set a specific 'Reply-To' address. 2. Open a posted Invoice and click the 'Send & Print' button. 3. Ensure the 'Email' method is selected and click 'Send'. 4. Observe the sent email in the chatter or the mail queue. Observation: The 'Reply-To' header is overwritten by the system's catchall or author email, ignoring the template setting. Cause: The 'account.move.send' logic processes email data via the '_get_mail_params' method. This method manually constructs a dictionary of parameters to be passed to 'message_post'. However, it only explicitly includes a fixed set of fields (author_id, body, subject, partner_ids, and attachments), effectively filtering out the 'reply_to' value. When 'message_post' is called without this key, Odoo's mail thread logic defaults to the standard '_notify_get_reply_to' calculation, causing the custom template configuration to be lost. Solution: Update the '_get_mail_params' method to safely extract the 'reply_to' value from the move data and include it in the parameters dictionary passed to the mail engine. opw-5922963
Website contact forms that create project tasks will no longer show missing fields as placeholder values such as "False" in the task description. This keeps task details clearer for users when optional form fields were removed or left unset.
Original PR description
# How to reproduce - Add a contact form to your website - Make it so the contact form creates a task on submit - Remove some field from the contact form, but no the email (ex: Phone) - Fill in the contact form; the email must be from one of the existing partners - Submit the form and go look at the task in the project application # The problem The fields removed from the form are still present in the task's description (ex: partner_phone: False) # Why This commit (https://github.com/odoo/odoo/commit/7d0660e034f3be1b92869c266dc2cfb0bc6b6941) changed the way the partner's data was added to the description. When adding that data, it does not check if it exists before hand and instead adds a default value if not found. opw-5920816 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252848
The website editor's Bold 19 shape has been adjusted to remove a thin unwanted line that could appear at some screen resolutions or zoom levels. This makes banner designs look cleaner and more consistent for website visitors.
Original PR description
Description of the issue/feature this PR addresses: In the website editor, shape Bold 19 has a thin line at certain resolutions/zoom levels. This is due certain inaccuracies with the calculated style. This commit brings this in line with what's done for the Bold 20 shape, by creating a bit of overlap. (NOTE: Open images at full size to see the difference!) Current behavior before PR: <img width="1919" height="861" alt="image" src="https://github.com/user-attachments/assets/f9ac02e6-9e89-4bf1-8f60-acdac8014e0f" /> Desired behavior after PR is merged: <img width="1918" height="847" alt="image" src="https://github.com/user-attachments/assets/a6808f48-e39f-41ec-8f6c-5738214ca412" /> Commit where these shapes were added, for reference: https://github.com/odoo/odoo/commit/81a2ff6d816bd6a279f6ce8fb5f935abc44f6518 How to reproduce the issue: 1) Enter website edit mode 2) Create a "Banner connected" block 3) Select "Bold 10" as the shape
This fix prevents the interface from crashing when a user quickly presses a key while adding a product line in an editable list. It improves reliability during sales order entry and avoids disrupting users in a common workflow.
Original PR description
When a record is in edit mode in an x2many list and the user presses a key while clicking "Add a product", onCellKeydownEditMode is called with record=null while editedRecord is set, causing a TypeError on record.dirty. Steps to reproduce: 1. Create a Sales Order 2. Click "Add a product" 3. While pressing the right arrow key, click "Add a product" again opw-6032870 Forward-Port-Of: odoo/odoo#254881
The shop search popup now closes automatically when a user enters website edit mode. This prevents the popup from blocking the floating toolbar, so editors can drag and add content snippets as expected on shop and product pages.
Original PR description
Steps to reproduce: - Go to the Shop and enable the floating toolbar. - Click the search icon in the header. - When the search modal opens, click 'Edit' to enable website editing. - Try to add a snippet from the floating toolbar. => The same issue also occurs on individual product pages. Observed behavior: Snippets cannot be added while the global search modal remains open. Expected behavior: Snippets should be draggable and added normally in edit mode. This PR ensures that the global search modal is closed when entering edit mode, preventing it from blocking add snippet. task-5905963 Forward-Port-Of: odoo/odoo#247781
This fix prevents Odoo's web testing framework from getting stuck when checking hierarchical records. It improves reliability for automated tests by ensuring repeated child records are not processed endlessly.
Original PR description
Problem: Triggering the `child_of` operator in the testing framework caused an infinite loop that froze Odoo. This occurred because the framework attempted to fetch all children of the root operand without accounting for already visited nodes, resulting in children being added indefinitely. Solution: Switched from using an `array` to `set` to prevent duplicate traversal. Task-6023290 Forward-Port-Of: odoo/odoo#255187 Forward-Port-Of: odoo/odoo#254857
This fixes a test issue where an operator's availability status could be read from outdated cached data after leave information changed in the same transaction. It helps keep automated checks reliable for live chat availability behavior without changing business workflows.
Original PR description
After sending a presence notification, `_send_status_updated_notification` leaves `im_status` cached on the user/guest record. If a related model that affects `im_status` (such as `hr.leave`) is modified afterwards in the same transaction, the ORM has no declared dependency on it and will not invalidate the cache. Subsequent reads then return the stale value. breaking PR: https://github.com/odoo/odoo/pull/249314 runbot-242076 Forward-Port-Of: odoo/odoo#255361
Users can now zoom in on product images in Product, Expenses, and Point of Sale screens. This makes it easier to inspect product details and creates a more consistent experience across these areas.
Original PR description
This PR enables the zoom feature for product images across the **Product**, **Expenses**, and **Point of Sale** modules. Currently, some product views display images without the zoom capability. This makes it difficult for users to inspect smaller details of a product. Enabling the `zoom` option on the `image_1920` widget provides a more consistent UI. ### **Changes** Added zoom to the following modules: **hr_expense** (product variant), **point_of_sale** (product view), and **product** (template and variant views). **Task ID: 6003499**
This update fixes an issue where currency rates for Bulgaria were incorrectly calculated after the country switched to the Euro. The system was using reversed rates from the data source, leading to inaccurate unit conversions. The change ensures correct rate calculations by using the primary 'RATE' value from the XML data.
Original PR description
Issue: after Bulgaria switched to EUR, currency rate fetching from BNB was incorrectly set to still use reversed currency rates from the fetched XML, resulting in unit-to-EUR and EUR-to-unit rates being flipped in the database. Solution: adjusting the parser to get rate from 'RATE' rather than 'REVERSERATE', as the XML provides both. task-6050519 Forward-Port-Of: odoo/enterprise#111275
This update fixes a potential issue where a user could indirectly change an employee's work email through salary configuration. Now, the work_email field is protected and will not be reset if the employee is linked to a user, ensuring data consistency and preventing unintended email updates.
Original PR description
Due to https://github.com/odoo/enterprise/pull/106974,the employee's work_email may be reset to False when creating or updating an offer. This behavior is acceptable if the employee does not have a linked user. However, if the employee is linked to a user, resetting work_email can allow a user to indirectly modify their own work_email through salary confi. To prevent this, we now ensure that work_email never changes if employee has a user linked to it. Steps to reproduce: - Hire an applicant from Recruitment (the employee has no work_email). - Set a random work_email and create a user for the employee. - Open the hired applicant and create a new offer to update the contract. - work_email should not be modified, even after new contract. task: 6033382
This update corrects a small, unintended message appearing in the documents generated for employee payroll. The fix ensures a cleaner and more professional presentation of these important documents. This change improves the overall user experience and consistency of our HR reporting.
Original PR description
Task#5980045 Forward-Port-Of: odoo/enterprise#109063
This update resolves a technical error that prevented the generation of 281.10 reports for Belgian payroll. The fix ensures accurate report creation by adjusting how the system identifies vehicle information, avoiding a previous traceback. This improves the reliability of payroll reporting.
Original PR description
[FIX] l10n_be_payroll: fix traceback in 281.10 sheets
Bug reproduction: Go to any version>=17.0 -> select belgium company -> install only belgium payroll (don't install fleet one) -> fill in niss, certification level, address, Time in R&D -> generate payslip and confirm it -> try to generate 281.10 report -> traceback
Bug cause:
1 - In traceback it was saying payslip doesn't have vehicle_id, in 281.10 sheet preparation (in function _get_atn_nature), there is a term like that
2 - Payslip doesn't have it because fleet module is not there.
Bug solution:
1 - Instead of checking the payslip has vehicle like that, we calculated it by using paylsip line_ids
2 - If the code ATN.CAR is there and the total of it is not zero, which means this payslip has a vehicle indeed.
task - 6037206
Forward-Port-Of: odoo/enterprise#111506
Forward-Port-Of: odoo/enterprise#110860This update resolves a technical issue that caused warnings during the initial setup of reports on some migrated Odoo databases. Specifically, it adds a backup method to identify accounts using their code when XMLIDs are missing, ensuring reports load correctly without errors. This improves the reliability of the reporting process.
Original PR description
Description of the issue this commit addresses: On some migrated BE databases, account template refs a4121/a4521 are missing as XMLIDs. l10n_be_reports then fails to recover partner/reconcile account refs and logs warnings during post-init load. --- Desired behavior after this commit is merged: This commit adds a fallback in BE report chart template data to resolve a4121/a4521 by account code when XMLIDs are missing, preventing recovery warnings while keeping normal XMLID behavior unchanged. --- runbot-[233845](https://runbot.odoo.com/odoo/runbot.build.error/233845)
This update resolves an issue where uploading documents to the 'All' folder in the Documents app prevented them from being viewable through the bridge interface. The fix ensures that 'All' folder uploads now default to the standard bridge folder, restoring full accessibility for users.
Original PR description
Problem: When a user uploads a document through a bridge to the Documents app, if the destination is set to the `All` folder, the file becomes unviewable from the bridge. It can only be accessed directly via the Documents app. Cause: This occurs because `All` is not an actual folder. Uploads directed to it default to the `My Drive` folder instead. Because `My Drive` is restricted and inaccessible via the bridge, the uploaded documents remain hidden. Solution: To solve this problem, this PR ensures that uploads directed to the `All` folder default to the default bridge folder rather than to `My Drive`. task-6023290 Forward-Port-Of: odoo/enterprise#111537 Forward-Port-Of: odoo/enterprise#111290
This update resolves an issue where users were directed to the wrong document form view when configuring PEPPOL document syncing settings. The change adds a dedicated Kanban view for PEPPOL documents within the settings, ensuring users can easily manage their PEPPOL documents. This improves the user experience and streamlines the configuration process.
Original PR description
Before this commit: clicking through on the setting of configuring the folder to sync peppol documents would lead to the document form view instead of the kanban view. Task-6040802 Forward-Port-Of: odoo/enterprise#111712 Forward-Port-Of: odoo/enterprise#111341
This update resolves a bug where users could incorrectly create 'Requested Documents' instead of folders when syncing Peppol documents. To avoid a complex workaround and a functional issue with folder placement, the ability to create or edit these documents through settings has been disabled. This ensures accurate Peppol document synchronization.
Original PR description
Before this commit a user could create or edit a folder in the accounting settings to sync peppol documents to. The issue was that this created a 'Requested Document' instead of a folder. This commit removes the possibility to create or edit documents through the settings. An alternative would have been to add the contex to create a Folder instead of a Requested Document, however another problem then arises: the folder is created in My Drive, which does not make any functional sense. Therefore we are disabling creation and edit. This is the same logic applied in 8ada2a4f. Task-6063736 Forward-Port-Of: odoo/enterprise#111761