Tuesday, August 25, 2026
45 changes · master
Enhancements to existing features
Website administrators can now manage guidance for AI crawlers through a dedicated llms.txt file from SEO settings. The update also centralizes crawler rules to keep technical, login, account, and checkout pages out of search results while preserving visibility for public content.
Original PR description
## Improve SEO crawler guidance with llms.txt and robots.txt updates ### Overview This PR enhances website SEO and crawler management by introducing support for `llms.txt` and improving `robots.txt`…
## Improve SEO crawler guidance with llms.txt and robots.txt updates ### Overview This PR enhances website SEO and crawler management by introducing support for `llms.txt` and improving `robots.txt` handling for technical pages. ### llms.txt Support * Add a dedicated `/llms.txt` route to serve LLM guidance files. * Add an editor in Website → SEO settings to manage `llms.txt` content directly from the backend. * Display a default placeholder when no content is configured, helping users create a valid markdown document. * Include a reference to `llms.txt` in the website root HTML to improve discoverability by AI crawlers and agents. ### robots.txt Improvements * Remove page-level `noindex` meta tags from technical pages. * Manage crawler restrictions through `robots.txt` directives instead. * Add disallow rules for technical and user-specific routes: * `/web/` * `/web/login` * `/web/signup` * `/web/reset_password` * `/shop/cart` * `/shop/checkout` * `/shop/payment` * `/shop/confirmation` * `/my/` * Generate route entries only when the corresponding modules are installed. ### Benefits * Provides a standard mechanism for communicating website usage guidelines to LLMs. * Centralizes crawler management through `robots.txt`. * Prevents indexing of technical and transactional pages while keeping public content discoverable. * Improves maintainability by generating crawler rules based on installed website features. ### **Task - 6120926** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Project digest tips now use clearer wording, more personalized content, and refreshed visuals to make guidance easier to understand. The To-Do app also gains new digest tips with relevant dynamic content, helping users discover useful workflows in regular updates.
Original PR description
- Improve Project digest tips with clearer wording, personalized content, and updated illustrations. Add new To-Do digest tips with dynamic content where applicable. task-5488231
French certified POS receipts no longer show the old unit price for special order lines such as discounts, tips, rewards, gift cards, event tickets, and linked sales orders. This makes receipts clearer for customers and reduces confusion around adjusted or non-standard order items.
Original PR description
In this commit: =============== We have removed the old unit price for the following special order lines: - discount line - tip line - reward line - gift card or e-wallet line - event ticket line - sale order or quotation line task-6212965 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Teams can now connect projects and tasks to sales order lines before the sales order is confirmed, helping firms begin long-running work earlier. Draft sales details and related timesheets remain hidden from portal users, so customers only see confirmed commercial information.
Original PR description
This commit's purpose is to allow user to link projects and tasks to sols that are still in draft. This is mainly for industries like architectural or engineering firms, where they tend to start working on long term project before the so is confirmed. However, those drafts sols should not appear for portal users. Sols and timesheets linked to draft So are hidden in all portal view. task-6276922 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale can now automatically create daily invoices even when a sales session remains open for multiple days. This helps businesses reconcile payments by day instead of dealing with one large combined invoice at session close.
Original PR description
Users do not necessarily close the session once a day. If a client close the session once a week, we currently have one combined payment/invoice, which is difficult for the user to then reconcile the payments. So a new option is added to automatically create an invoice every day, even if the session is still open. This will allow the user to reconcile the payments more easily. taskId: 6388266
Point of Sale order edits are now automatically recorded in the order chatter without requiring a separate configuration setting. This makes changes easier to audit and reduces setup steps for businesses using PoS, restaurant, employee, or self-order flows.
Original PR description
*: point_of_sale, pos_hr_restaurant, pos_restaurant, pos_self_order Before this commit: ----------- - Tracking edited PoS orders in the chatter required enabling a dedicated configuration option. After this commit: ----------- - Edited PoS orders are always tracked in the chatter, removing the need for any additional configuration. Related PR: - Upgrade: https://github.com/odoo/upgrade/pull/10837 Task-6400946
Greek localization now supports myDATA VAT categories 9 and 10 for Article 31 VAT rates of 3% and 4%. It also improves invoice classification validation so users only see compatible default options, reducing reporting mistakes.
Original PR description
myDATA defines categories 9 and 10 for the Article 31 VAT rates of 3% and 4%. These categories were not supported, so this commit adds full support to them. --- Filter the default classification against the current invoice type and available category and type, preventing incompatible values from appearing as disabled selections. task-[6414111](https://www.odoo.com/odoo/project/967/tasks/6414111) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The payment confirmation and order placed screens now share a unified look and feel, including consistent progress steps, card styling, and merchant branding colors. This makes the checkout journey feel smoother and more professional for customers using online POS and self-order flows.
Original PR description
*: payment, pos_self_order Before this commit, "confirming payment" and "order placed" looked like two unrelated pages — a generic spinner vs. a checkmark on a different background, no shared branding, despite being one continuous customer flow. This commit gives both screens one consistent design: a shared step-progress indicator, matching card/badge styling, and the merchant's own POS color applied consistently across both, so the payment-to-order journey now reads as a single, cohesive experience. task-6341668 requires: https://github.com/odoo/enterprise/pull/124275 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Automated messaging actions are now easier to understand and use for emails, chatter messages, notes, and SMS. This helps teams configure customer and internal communications more reliably, with clearer options and more consistent behavior.
This update improves how Odoo stores, copies, and updates translated field values across business records. It helps preserve translated content more consistently when records are edited or duplicated, reducing translation loss and manual cleanup for multilingual databases.
Original PR description
[IMP] orm: write StoredTtranslations Develoepers can directly write StoredTranslations objects to record fields. And the ORM will keep the whole entity when flushing. [IMP] orm,tools: make field.copy callable for mark_as_copy make field.copy can be callable in ORM provide a tool mark_as_copy to create a callbale for field.copy which can easily append a translated ' (copy)' to each translated value when copying. This allows developers to drop translations for model translated fields. https://github.com/odoo/enterprise/pull/125493 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The activity scheduling wizard is easier to read and use, with clearer plan summary styling, improved spacing, and a more prominent meeting scheduling button. This helps users understand the next step faster and reduces friction when planning activities or calendar meetings.
Original PR description
This commit introduces several visual and usability improvements to the activity schedule wizard: - "Plan Summary" Label: Removes the default muted styling applied to readonly fields by forcing standard body text color and bold font weight, making the section header more legible. Unused `colspan` attributes outside of a `<group>` have also been cleaned up. - Kanban Spacing: Adds right padding (`pe-2`) to the deadline date in the schedule summary list for better visual breathing room and alignment. - Calendar Integration: Promotes the "Schedule" meeting action from an inline link to a primary action button in the footer. The inline area now displays a clear "Pick a date and time" instruction, making the primary action more obvious and consistent with standard flows. Task-6485315
Odoo’s batch picking capability has been moved directly into the core Inventory app instead of requiring a separate add-on. This simplifies setup and makes batch operations easier for other logistics, delivery, fleet, and localization features to use without extra bridge modules.
Original PR description
TODO task-6154300 **Enterprise PR**: odoo/odoo#124078 **Upgrade PR**: odoo/upgrade#10771
This update improves several Odoo interface icons so they are easier to understand, including quote, table, heading, date, image, and favorite indicators. It also standardizes small visual elements such as kanban state bubbles and editor controls, reducing misalignment and improving consistency across apps.
Original PR description
PR enterprise: https://github.com/odoo/enterprise/pull/128414 [FIX] website, html_editor: use filled quote icons --- __Problem__ The outlined `format_quote` icon reads as a pair of `99` digits rather…
Warehouse teams can now generate serial and lot numbers directly while using the barcode app for deliveries. This removes the need to switch to the backend system, helping deliveries move faster and reducing manual work.
Original PR description
It's not possible to automatically generate serial numbers and lot numbers through the barcode application. While this is possible in the backend. This commit adds the popup so that barcode users can accept deliveries and generate serial numbers on the fly. Task-5469775
The Sign app now presents a cleaner signing interface by moving Download into the options menu and renaming Resend to Reminder. Visual refinements to field borders and drag indicators make document preparation and signing feel more consistent and polished.
Original PR description
Before this fix: Read only field borders were thicker than other fields. The Download button was shown as a standalone button during signing. The drag helper line showed in yellow while dragging a field. The "Resend" button label was unclear in context. After this fix: Drag helper color changed to an appropriate shade and the read only field border thickness was reduced. The Download button was moved into the gear menu. The "Resend" button was renamed to "Reminder" for better clarity. Impact: Moving the Download button into the gear menu keeps the signing toolbar focused, renaming "Resend" to "Reminder" better reflects the action's intent, and aligning the drag helper color and field border thickness with the rest of the UI ensures a more polished signing experience for both senders and signers. Task ID - 6334775
Payroll journal entries now respect the anonymization setting by removing employee names when payslips are validated. This helps protect employee privacy and ensures payroll accounting records do not expose personal information when anonymization is enabled.
Original PR description
When we check the option `Anonymize journal entries` in the settings and we validate a payslip, in the journal entry of the payslip, we still see the names of the employees for which the payslips have been validated. Names should be removed to ensure anonymization. __ task-6469001
Sales commission plans now offer clearer controls, including read-only achievement settings, making them easier and safer to review. Commissions based on paid invoices now use the actual payment reconciliation date, so payouts land in the correct period and reduce manual HR adjustments.
Original PR description
task-6342052
Appointment types can now have a designated responsible user who can manage them when the original creator is unavailable. New bookings use that responsible user as the organizer, so related emails come from the right person instead of the original creator or a generic database address.
Original PR description
Appointment type allowed editors are `create_uid` and `staff_user_ids → if the create_uid leaves the company, editing options are limited. Issue 1 You have to get the sysadmin to intervene when you want to edit some things on the appointment type. Issue 2: Emails are still sent from "create_uid@dbname.odoo.com" --- In debug mode, we can now set a user to be responsible for an appointment type. The responsible user gains write/delete rights for that appointment type. If a responsible user is set, new bookings will be created with them as the organizer. Consequently, mails will be sent from them Task-6349168
Point of Sale can now automatically create invoices each day, even when a sales session remains open for several days. This makes payment reconciliation easier by avoiding one large combined invoice for an extended period.
Original PR description
Users do not necessarily close the session once a day. If a client close the session once a week, we currently have one combined payment/invoice, which is difficult for the user to then reconcile the payments. So a new option is added to automatically create an invoice every day, even if the session is still open. This will allow the user to reconcile the payments more easily. taskId: 6388266
This update refines how timesheet-related information is handled across service tasks and helpdesk tickets. It helps teams keep project, support, and billing follow-up more consistent after related community changes.
Original PR description
task-6276922
Document users can now access and manage spreadsheet templates from the configuration area, while template visibility can be limited by user groups. This helps organizations make templates available to the right people and prevents non-document users from creating templates where they should not.
Original PR description
- Add configuration access to their spreadsheet template for document user - Allow the restriction of read access to template based on groups - Hide the function to create template from spreadsheet to non-document_user Task: 6401925
This update improves how translated text is preserved and adjusted when business records are copied. It helps keep labels and names consistent across languages, including automatically adding a translated copy marker where needed.
Original PR description
[IMP] orm: write StoredTtranslations Develoepers can directly write StoredTranslations objects to record fields. And the ORM will keep the whole entity when flushing. [IMP] orm,tools: make field.copy callable for mark_as_copy make field.copy can be callable in ORM provide a tool mark_as_copy to create a callbale for field.copy which can easily append a translated ' (copy)' to each translated value when copying. https://github.com/odoo/odoo/pull/272177
The VoIP phone numbers list now includes a Refresh button so users can update the displayed numbers on demand. This helps teams confirm the latest phone number information without leaving the page or waiting for an automatic update.
Resolved issues and error corrections
Fixes an Accounting issue where reversing and recreating foreign-currency invoices with cash-basis taxes could skip exchange difference and cash-basis journal entries. This ensures credit notes created through the standard reversal flow reflect currency rate changes automatically, avoiding manual draft/reset workarounds and improving accounting accuracy.
Original PR description
### Issue before this commit: When using the "Reverse and Create Invoice" feature on a posted invoice with a foreign currency and Cash Basis enabled, the expected Exchange Difference and Cash Basis…
PR enterprise: https://github.com/odoo/enterprise/pull/128414 [FIX] website, html_editor: use filled quote icons --- __Problem__ The outlined `format_quote` icon reads as a pair of `99` digits rather than as quotation marks, which makes every blockquote-like snippet look like it contains stray numbers. __Quick fix__ Add `oi-filled` to all `format_quote` icons in the website snippets and to the powerbox commands inserting them. Also make the powerboxW forward `iconClass` from the command definition, some command used it but it wasn't working. [IMP] *: better icon choices and alignment fixes --- *: html_builder, html_editor, iot_drivers, web, website, website_event_track __What__ - Use clearer icons now that they are available: `table` for table insertion, `format_h1`-`format_h3` in the powerbox headings, `shadow` for the image shadow, `format_image_left` for wrap text, `crop_square` for buttons, `recenter` for background position, `center_focus_weak` for "select only this block", `today` in the builder date picker, `chevron_forward` for toggle lists, `person_add` and `person_remove` for the avatars buttons, and a star instead of a bell for the event track favorite. - Fix alignments: editor switch rebuilt on relative sizes instead of hardcoded pixels, image rotator handle styled in SCSS instead of inline, and toolbar height. - Force the icon font family so a surrounding font declaration cannot break icon rendering. - Add `undo` and `redo` to RTL entries so they get flipped like the other directional icons. - Remove `chevron_left`/`chevron_right` from RTL entries because they represent absolute direction unlike `chevron_backward` and `chevron_forward`. - Remove obsolete `google-plus` custom icons from the media dialog. task-6377407 [IMP] event, project, maintenance, web: clean kanban state selection bubble --- __Problem__ Each module redefined the state bubble size and position with its own pixel and em tweaks, both in the badge and in the dropdown. The result was slightly different sizes and misalignments from one model to the other. __Quick fix__ Size the bubbles from the shared bubble variables and move the dropdown item alignment to a single rule in `view.scss`, then remove the per-module overrides. Also drop the now useless `oi-lg` classes and fix a missing `this` in the event template. task-6377407 [IMP] web: add new icons for diverse usages --- __What__ Extend the icon wishlist and regenerate the Material Symbols subset fonts with ~15 new icons: heading levels (`format_h1` to `format_h6`), `format_image_left`, `format_image_right`, `table`, `today`, `shadow`, `recenter`, `crop_landscape`, `center_focus_weak`, `rotate_right` and `view_timeline`. Also refresh the search tags of a few icons and force `close_small` as outline-only, since the generator wrongly detects a filled variant for it. task-6472088
### Issue before this commit: When using the "Reverse and Create Invoice" feature on a posted invoice with a foreign currency and Cash Basis enabled, the expected Exchange Difference and Cash Basis tax entries are not generated upon the automatic reconciliation. The credit note is successfully created and reconciled with the original invoice, but the P&L exchange difference and the cash basis transition lines are completely missing. Currently, the only workaround is to manually reset the generated credit note to draft and re-post it, which forces the system to correctly calculate the currency rate differences and generate the missing entries. ### Steps to reproduce the issue: 1. Download Accounting 2. Go to Settings > Cash basis. Tick it and set as 'Base Tax Received Account' an account like 201000 Current Liabilities 3. Go to Chart of Accounts > search your account (ex. 201000 Current Liabilities) and be sure the flag of 'Allow Reconciliation' is on 4. Go to Taxes > 15% sales > set 'Tax Exigibility' as Based on Payment and 'Cash Basis Transition Account' always as 201000 Current Liabilities 5. Go to Currencies and set a new currency like MXN inserting tax rates as: 1. 1 july 2026: 20$ 2. 15 july 2026: 15$ 6. Create a new invoice with price 100 and 15% tax, set MXN as currency for the journal, set the date as 1 july and confirm it 7. Click on 'Credit Note', then 'Reverse and Create Invoice' and confirm it 8. go back to the invoice and see that after the total amount there is a new line 'Reversed on...' 9. After that line there should also be the line with the Exchange Difference since the tax rates for MXN currency were different at the moment of the invoice and at the moment of the credit note. This is only created by resetting to draft the credit note and confirm it again. ### Cause of the issue: In the account.move.reversal wizard, when is_modify = True (Reverse and Create), the system triggers _reverse_moves with cancel=True. At the end of the _reverse_moves method, the newly created reverse moves are automatically posted and reconciled. However, this automatic posting is executed with move_reverse_cancel=True injected into the context: reverse_moves.with_context(move_reverse_cancel=cancel)._post(soft=False). When the reconciliation engine (_reconcile_plan_with_sync and _create_exchange_difference_moves) detects this specific context key, it intentionally bypasses the creation of both the exchange difference P&L moves and the cash basis entries, treating the reversal as a pure administrative cancellation rather than a financial operation with currency fluctuations. ### Reason to introduce the fix: To ensure financial accuracy and compliance, especially when cash basis and multi-currency are involved, a reversal on a different date must reflect the actual exchange rate fluctuations and properly trigger cash basis rules. By removing the move_reverse_cancel context injection during the automatic posting of the reverse moves, we allow the native reconciliation engine to evaluate the newly computed balance (based on the credit note's date) against the original invoice. This ensures that exchange differences and cash basis journal entries are automatically and accurately generated on the first attempt. opw-6399867 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283306 Forward-Port-Of: odoo/odoo#281498
Cloud storage download links can now be generated with a longer expiry time when needed by workflows that send files to external services. Existing behavior remains unchanged by default, reducing disruption while preventing delayed downloads from failing.
Original PR description
Some features hand a cloud storage download URL to an external service that may fetch it later. The default five-minute lifetime is too short for those flows. ### Steps to reproduce 1. Configure a cloud storage provider (e.g. cloud_storage_google). 2. Upload a large file from the web client, so it is stored in the cloud. 3. Generate a download URL for a consumer that may fetch it after five minutes. 4. The URL expires before the consumer fetches it. ### Cause The Google and Azure providers always use the default download URL lifetime, so callers cannot request a longer-lived URL. ### Fix Read an optional cloud_storage_download_url_time_to_expiry context value when generating a download URL. Keep the existing five-minute lifetime as the default for all current callers. opw-5424132 Related Enterprise PR: odoo/enterprise#105967 Forward-Port-Of: odoo/odoo#246443
This update corrects how replacement pay is calculated on Belgian payslips in specific absence and contract situations. It prevents replacement amounts from being filled when a regular amount is already present, and sets them to zero for unpaid non-assimilated leave and out-of-contract lines, improving payroll accuracy.
Original PR description
. If Amount is filled, Replacement Amount is empty. . LEAVE_UNPAID_NON_ASSIMILATED categories, will have zero Replacment amount . Out Of Contract lines, will have zero Replacment amount . Add the Corresponding tests task-6479842
Fixed an issue that could cause an error when users edited the text of a social media post. This helps ensure smoother content editing and prevents interruptions while preparing social posts.
Original PR description
Bug === A traceback is raised when editing the body of a text field with `onchange_on_keydown`. This happen in social when editing the post body. Task-6323897
WhatsApp messages now send attachments stored in cloud storage as working file links instead of empty files. This ensures recipients receive the intended documents while preserving the existing behavior for locally stored files.
Original PR description
WhatsApp attachments were delivered as empty (0 byte) files when they were stored through the cloud_storage module. ### Steps to reproduce 1. Install and set up whatsapp and a cloud storage module (e.g. cloud_storage_google). 2. Send a file through WhatsApp. 3. The recipient receives an empty file. ### Cause A cloud stored attachment keeps only a reference to its remote data, so its raw field holds no bytes. The integration uploaded those empty bytes to WhatsApp. ### Fix Use the attachment HTTP stream to generate a long-lived cloud storage URL and pass it to WhatsApp as the media link. Pass ordinary remote attachment URLs directly, and keep uploading local attachment bytes as before. opw-5424132 Related Community PR: odoo/odoo#246443 Forward-Port-Of: odoo/enterprise#105967
This fix prevents Odoo from crashing when a user navigates away from a view while embedded content in an HTML field is still loading. The system now safely cancels that pending display action, improving stability without changing normal user workflows.
Original PR description
[Adoption of Owl v3.0.0-alpha.42] in Odoo codebase introduced timing differences when mounting a new App (sub-)root. This timing difference could cause a crash when mounting an embedded component in…
[Adoption of Owl v3.0.0-alpha.42] in Odoo codebase introduced timing differences when mounting a new App (sub-)root. This timing difference could cause a crash when mounting an embedded component in a html field, if the main App switched view away from the field where embedded components were waiting for their root to prepare, the root host wouldn't be in the DOM anymore, but the code would still try to mount these components. To avoid the issue, this commit makes use of `onBeforeComplete` to abort a pending mount if the owner instance (Component, editor plugin, ...) was destroyed before the mount could be initiated. This is the best strategy to silently ignore crashes caused by premature destruction of an ancestor while still keeping errors thrown when the host was removed from the DOM for other reasons that may need investigation. Aborting when the host is disconnected is the best strategy to avoid the crash entirely, but then we might miss those other reasons. [Adoption of Owl v3.0.0-alpha.42]: https://github.com/odoo/odoo/commit/acb95b28ab807b37ee86b381b555e38fae36ae93 runbot-944116 Forward-Port-Of: odoo/odoo#284206
This update makes time- and date-based labels refresh automatically, so open Odoo screens no longer show stale values such as yesterday's messages marked as today. It also improves efficiency by only updating these time-based values when they are actually being viewed.
Original PR description
Dates are currently not reactive, so they don't play well when used inside reactive contexts (components, computed, ...). Changes to date are never detected, which can lead to inconsistencies. This PR introduces several commit to fix this issue in an efficient way. See individual commits for details. https://github.com/odoo/enterprise/pull/128366
This fixes an error that could appear when using the QR code feature in Point of Sale self-ordering. Businesses can expect a smoother experience for staff and customers when generating or accessing QR codes.
Original PR description
In this commit: ------------------ - Fixed the incorrect way of accessing props, which was causing a traceback. Props are now accessed correctly using `this.props..` instead of `props....` task: 6395641
This fixes an internal error that could occur when opening the Purchase reporting pivot view. The change makes report query handling more robust when grouping data, helping users access purchase analysis without interruption.
Original PR description
Use the freehash because the arguments can be mutable (like a list which will become an ARRAY).
Before this, in Purchase -> Reporting -> Purchase -> Use pivot view, the code `SQL(", ").join(unique(grouping_sets_sql))` can raise because 2 sets can contain lists.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prWebsite charts and other canvas-based visuals are now better recognized by screen readers, reducing accessibility gaps for visually impaired users. Chart snippets can also include a description so assistive technologies can explain the chart content more clearly.
Original PR description
Adding role="img" to a <canvas> element forces assistive technologies like screen readers to treat the pixel-based drawing as a single static image. Without it, screen readers cannot parse the visual content inside the canvas, resulting in a blind spot for visually impaired We'll work to add a description on canvas elements later. Task-6009931
The website mega menu now appears in the same aligned position whether submenus open on click or on hover. This improves navigation consistency while preventing menus from closing unexpectedly as users move the cursor.
Original PR description
### Issue: The mega menu position is inconsistent between the two "Sub Menus" options. With "On Click", the mega menu opens below the navbar, which is its default position. With "On Hover", it opens…
### Issue: The mega menu position is inconsistent between the two "Sub Menus" options. With "On Click", the mega menu opens below the navbar, which is its default position. With "On Hover", it opens directly below the mega menu toggle, making it visually misaligned with the "On Click" behavior. ### Reason: The different positioning for "On Hover" was intentional. If the mega menu were placed in its default position, the gap between the toggle and the mega menu would cause the cursor to briefly leave both elements while moving between them, unintentionally closing the mega menu. To prevent this, the mega menu was positioned directly below the toggle, removing that gap. ### Fix: Restore the mega menu to its default position for "On Hover" to match the "On Click" behavior. To prevent the original issue of the mega menu closing while the cursor travels from the toggle to the mega menu, introduce an invisible hover bridge. The bridge is implemented as a pseudo-element of the mega menu toggle, ensuring the cursor never leaves the hover area while crossing the gap. For header templates, such as "Menu - Sales 1" and "Menu - Sales 4", the hover bridge overlaps interactive content in the navbar. To avoid this, position the mega menu below the menus container instead of below the navbar for these specific headers in both "Sub Menus" options. This results in a consistent mega menu position while preventing unintentional menu closure during cursor movement. task-[6116253](https://www.odoo.com/odoo/all-tasks/6116253) Co-authored-by: Arib Ansari <<aans@odoo.com>> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Orders placed online for in-store pickup with payment on site are now shown correctly in the POS order list. This lets store staff find and fulfill those orders as expected, avoiding missed or delayed pickups.
Original PR description
Step To Reproduce: - install `sale_management` and `website_sale_collect` and POS with demo - go to shop page, add a product -> checkout - Use `Pick Up in Store` feature and `Pay on site` payment…
Step To Reproduce:
- install `sale_management` and `website_sale_collect` and POS with demo
- go to shop page, add a product -> checkout
- Use `Pick Up in Store` feature and `Pay on site` payment method -> confirm
- notice a Sale order is created for this
- Open POS, try to fulfill the linked SO, by clicking on `Quotation/Order`
Observation:
- The SO is not visible in the list view
Cause:
- clicking on `Quotation/Order` initiates a search with domain `["amount_unpaid", ">", 0]`
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/pos_sale/static/src/app/components/screens/product_screen/control_buttons/control_buttons.js#L16
- `amount_unpaid` depends on `amount_paid` which is sum of all transaction in ("authorized", "done") state
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/sale/models/sale_order.py#L913-L916
- after commit [1], transactions with payment method of type `postpaid` are considered as `done` (`Pay on site` is postpaid)
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/website_sale_collect/models/payment_method.py#L9-L14
https://github.com/odoo/odoo/blob/21e3b547e486951421e39733c19a8a2d54361e00/addons/payment_custom/models/payment_transaction.py#L40-L41
- this makes `amount_paid ` to be full order amount and `amount_unpaid = 0` for the order and search fails in pos
[1] https://github.com/odoo/odoo/commit/9d01784fa9980fb9e4989e6e4e9f35909665e6ca
Fix:
- Fix the compute of `amount_unpaid` and do not count transactions amount from
postpaid payment method
Note: issue occurs for POS only, hence, we avoid changing anything from sale side
while keeping changes to minimum
opw-6424288
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#280864Fixed an issue in Restaurant Point of Sale where splitting a bill with combo meals could select only one repeated combo item instead of the full quantity. This helps restaurant staff split orders accurately and avoid billing mistakes when customers choose the same combo option multiple times.
Original PR description
Steps to reproduce: --- - Install `pos_restaurant` demo data. - Open a session for `Restaurant`. - Go to any table. - Add a Sushi Lunch Combo line with the same sushi choice multiple times. - Click the "More" button and select "Split". - Click on any combo product line. Issue: --- - Only one quantity is selected instead of the full combo choice quantity. Cause: --- - Combo child lines were incremented by a fixed value of `1` during split, without considering the quantity ratio between the combo root line and combo child lines. Fix: --- - Compute the selection step based on the combo line quantity relative to the combo root line quantity. - Properly update split quantities for repeated combo choices. - Added test coverage for combo lines with repeated quantities. task-6197879 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283876 Forward-Port-Of: odoo/odoo#264049
Sales users limited to their own documents can now cancel confirmed sales orders that include loyalty programs without hitting an access error. This prevents unnecessary administrator intervention and keeps order cancellation workflows moving smoothly.
Original PR description
Steps to produce: --- - Install `sale_management` and `sale_loyalty` module without demo. - From sales > products > discounts & loyalty, create new loyalty card program and save. - Now create new…
Steps to produce: --- - Install `sale_management` and `sale_loyalty` module without demo. - From sales > products > discounts & loyalty, create new loyalty card program and save. - Now create new product of 100$. - Create a user which have sales rights as `user: own documents only`. - With that user, create new sale order with product and confirm. - Try to cancel the order. Issue: --- - It shows the access error: ```py You are not allowed to delete 'Sale Order Coupon Points - Keeps track of how a sale order impacts a coupon' (sale.order.coupon.points) records. This operation is allowed for the following groups: - Sales/Administrator Contact your administrator to request access if necessary. ``` Root cause: --- - Users with the `Sales: Own Documents Only` access right only have read permissions ([1]). When they cancel a Sales Order, the `_action_cancel` method attempts to clean up the temporary pending points allocated to the order by calling `self.coupon_point_ids.unlink()`. Because this call is executed without elevated privileges, the system blocks the deletion and raises an Access Error Solution: --- - Added `.sudo()` to the `unlink()` call for `coupon_point_ids` in the `_action_cancel` method. This ensures the pending point records are cleaned up with the necessary elevated privileges. [1]https://github.com/odoo/odoo/blob/23af2b443735c6d3a2f64e44f9ea5da45638b052/addons/sale_loyalty/security/ir.model.access.csv#L16 opw-6453016 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284122 Forward-Port-Of: odoo/odoo#281477
This fix prevents customer and pickup details from disappearing when a guest returns from the online payment page in restaurant self-ordering. It ensures order information is saved before leaving for payment, reducing lost draft data and improving checkout reliability.
Original PR description
**Setup** * Increase the debounce time of `debouncedSynchronizeLocalDataInIndexedDB` to **5 seconds** to reproduce the issue deterministically. * Configure a restaurant with **Self Ordering** enabled…
**Setup** * Increase the debounce time of `debouncedSynchronizeLocalDataInIndexedDB` to **5 seconds** to reproduce the issue deterministically. * Configure a restaurant with **Self Ordering** enabled (`QR Menu + Ordering`). * Configure **Mollie** as the **only** online payment method. **Reproduction** 1. Place a **takeout** order through the mobile menu. 2. Select a pickup time, enter the required customer information (including a mobile number), and proceed to the payment page. 3. Verify from the backend that the draft order contains the expected data (customer/partner and `preset_time`). 4. Press the browser **Back** button to return from the payment page. 5. Check the draft order in the backend again. [video](https://drive.google.com/file/d/1kNWpYuo79mYMV3eMelwJ5IDFeWUc7zsD/view) **Observed result** * The draft order loses its previously synced information. In particular, the **partner/customer** data (and other synced fields such as `preset_time`) are removed. **Expected result** * Returning from the payment page should not modify the draft order. All previously synced data should remain intact. **Cause** - When there's only a single payment method, it's [auto-selected](https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/pos_self_order/static/src/app/pages/payment_page/payment_page.js#L21-L22) and `checkAndOpenPaymentPage` immediately opens the payment page via[ window.open()](https://github.com/odoo/odoo/blob/161715c850496d3683baa5d1600380470d0b5ff5/addons/pos_online_payment_self_order/static/src/app/pages/payment_page/payment_page.js#L35). - The order's local data is saved to IndexedDB on a 300ms debounce. If the redirect fires before that debounce completes, the save is cancelled, leaving IndexedDB out of sync with the in-memory order **Fix** - Before opening the payment URL, explicitly flush the order to IndexedDB using the `synchronizeLocalDataInIndexedDB`, ensuring the local data is persisted before the page navigates away. opw-6231478 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283800 Forward-Port-Of: odoo/odoo#272724
Payslip reports and payroll screens now display titles, labels, worked days, and line items in the correct language instead of mixing employee, location, and user languages. This improves Belgian bilingual payslip compliance and makes payroll information clearer for HR teams and employees.
Original PR description
Payslips in Belgium must be printed in two languages (DMFA location and employee). However, the translation didn't seem to work as intended and there was an awkward mix of languages across both…
Payslips in Belgium must be printed in two languages (DMFA location and employee). However, the translation didn't seem to work as intended and there was an awkward mix of languages across both reports and views. While printed reports showed the payslip lines correctly translated, their labels and title stayed in the employee's language, and worked days reflected the active user's language. In backend views, the title used the employee's language, the lines used the DMFA language, and worked days used the active user's language. This behavior was caused by context language overriding and how the names were handled: - The XML report templates explicitly forced the language context to the employee's language, bypassing the Python logic that already set the correct environment language before rendering the templates. This is why the static text of the report stayed in the employee's language. - The `name` fields on `hr.payslip.line` and `hr.payslip.worked_days` acted as editable virtual related fields fetching a string from `salary_rule_id` or `work_entry_type_id`, with additional logic. Fields like that cannot be translated directly, and they were not being recomputed when the environment language changed (impossible for a stored field anyway). As a result, they were locked in the language they were first created in. - In Python, the language context was manually forced during line evaluation to the employee's language (or DMFA language in Belgium) specifically to populate those stored `line.name` fields upon creation. Combined with how the `name` field was defined, this locked the strings shown in backend views to that initial DMFA language. - To translate lines in reports despite those locked values, the XML templates used a workaround: checking if the slip was translated to print the translatable `line.salary_rule_id.name` instead of `line.name`. This explains why the payslip lines were the only part of the report that was translated correctly. - The payslip's `name` field was also a stored computed field that explicitly forced the employee's language both when translating the title string and when formatting period dates. Besides fixing the translations on printed reports, we decided it makes more sense for backend views to have everything in the active environment language. To fix this consistently across both views and reports, this commit applies the following changes: - Removed context language overrides from all report templates. - Removed the helper method forcing language context during computation. - Introduced a `custom_name` field on `hr.payslip.line` and `hr.payslip.worked_days`. - Made the `name` fields on `hr.payslip.line` and `hr.payslip.worked_days` non-stored computed fields depending on context language. They now return `custom_name` if set, or dynamically recompute the translated default string. The inverse method saves manual user edits to `custom_name`. - Cleaned up the reports to simply print the `name` field of each payslip line, removing the fallback workaround logic. - Updated the payslip's `name` field compute method (and date formatting helpers) to rely and depend on `self.env.lang` instead of the employee's language. Made this `name` field non-stored as well: storing it was useless since it was not editable in the form view (only `title` is), and would have prevented recomputation based on environment language changes. - Adapted the rest of the code, including half-day management in Belgium by adding a new `l10n_display_half_day` field to properly compute the name like before. - Deleted every assignment for the `name` fields that are now unstored. See odoo/upgrade#11092 Task-6432137
Point of Sale now includes partially paid invoices when preparing customer account settlements. This lets staff complete outstanding balances directly from the PoS instead of needing a separate back-office step.
Original PR description
Before this commit: ------------- - Only unpaid invoices were loaded into the PoS for settlement. - Partially paid invoices were not loaded and therefore could not be settled from the PoS. After this commit: ------------- - Load partially paid invoices into the PoS so they can also be settled from the PoS. Task-6438716
Fixed an issue that could prevent shortcuts from being created for documents shared with a group. The update also makes owner access handling more reliable when group-based access is assigned, helping teams share and organize documents without unexpected access problems.
Original PR description
Reproduce: try creating a shortcut for a document shared with a group. \+ increase robustness of logging owner access when creating a documents with an access command regarding a group. Task-6344800 Forward-Port-Of: odoo/enterprise#128926
Fixed an issue that prevented Colombian electronic vendor bill PDFs from being generated after the reception workflow. The system now correctly reads the invoice data when it is stored inside a compressed attachment, avoiding server errors and ensuring users can print the PDF as expected.
Original PR description
**Steps to reproduce:** * Install the **l10n_co_dian** module. * Go to **Settings** and, under **Colombian Electronic Invoicing**: * Disable **Testing Mode**. * Enable **DIAN Demo**. * Create a…
**Steps to reproduce:**
* Install the **l10n_co_dian** module.
* Go to **Settings** and, under **Colombian Electronic Invoicing**:
* Disable **Testing Mode**.
* Enable **DIAN Demo**.
* Create a vendor bill with a tax and confirm it.
* Click **Acknowledge Reception**.
* Click **Receive Goods**.
* Click **Accept**.
* From the gear menu, click **Print → Invoice PDF**.
**Observed behavior:**
* A server error is raised:
```
lxml.etree.XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1
```
* The PDF cannot be generated.
**Cause (two-step):**
1. **ZIP not unwrapped:** The original code called `etree.fromstring(self.l10n_co_dian_attachment_id.raw)` directly for all move types. For vendor bills (`in_invoice`) the attachment is stored as a ZIP file, so `raw` is compressed binary data — not XML. Passing it to `etree.fromstring` directly produces the `XMLSyntaxError` above.
2. **AttachedDocument wrapper not unwrapped:** Once the ZIP is correctly decompressed with `xml_utils._unzip`, the resulting XML is an `AttachedDocument` wrapper, not a plain `Invoice`. The actual invoice XML is embedded as CDATA inside `cac:Attachment/cac:ExternalReference/cbc:Description`. `_get_qr_code_value` expects the inner document and searches for nodes like `cac:AccountingSupplierParty`, `cac:LegalMonetaryTotal`, and `sts:QRCode` — none of which exist on the outer wrapper, so the QR code was blank or the method crashed.
**Fix:**
* In `_l10n_co_dian_get_invoice_report_qr_code_value`, for vendor bills (`in_invoice`/`in_refund` without support document), unzip the attachment and immediately attempt to extract the inner invoice XML from `cbc:Description` using `findtext('.//{*}Description')` (lxml namespace wildcard). If the node is present, parse its text as the actual document; otherwise fall back to the unzipped bytes directly.
**Note:**
* A unit test for the `AttachedDocument` unwrapping path was not added because the test would require a zipped fixture file (the vendor bill attachment is stored as a ZIP) which is not appropriate to commit.
* A regression test was added in `test_accept_by_customer`: after the full commercial event flow the method is called inside a `try/except etree.XMLSyntaxError` block so that any XML parse failure surfaces as a proper test *failure* rather than an unhandled test *error*.
opw-6417422
Forward-Port-Of: odoo/enterprise#128908
Forward-Port-Of: odoo/enterprise#126463This fixes an issue in Brazilian POS electronic invoicing where the system could select the wrong tax configuration when sales and purchase taxes shared the same code. The correction helps prevent unbalanced accounting entries, improving reliability of POS tax reporting and bookkeeping.
Original PR description
The chart template gives the same Avatax code and price_include_override to the sale and the purchase tax, and creates both in the same transaction. Without an explicit type_tax_use the lookup used to return either of them at random, and picking the purchase one left the entry unbalanced. The purchase taxes got their Avatax code in 18.4+. https://github.com/odoo/enterprise/pull/101072 runbot-945969 Forward-Port-Of: odoo/enterprise#128872 Forward-Port-Of: odoo/enterprise#128476
Restores the HSBC H2H MRI file export option for Hong Kong payroll and autopay users after it was unintentionally removed. This ensures businesses can generate bank payment files with the required header format when submitting payments through HSBC.
Original PR description
In 19.2, during a refactor, the H2H feature for MRI file export (HSBC) was wrongly removed from the system. This makes it impossible to export a file with the correct file level header when needed. It would be difficult to add it back in stable, so we first update the master version to make sure it is back by Odoo 20. Note that instead of a setting like before, we decided to reintroduce it as a separate file type instead. task-6500843
VoIP user synchronization now has more time to complete before timing out. This helps reduce failed setup or update operations for phone users, especially when the process takes longer than expected.