Tuesday, August 25, 2026
47 changes · master
Resolved issues and error corrections
Sales screens now show colons after short stacked field labels, making the labels easier to read and visually consistent. This is a small polish fix that improves clarity without changing any business workflow.
Original PR description
Improve the aesthetic of labels of stacked fields by adding colons at the end e.g., M -> M:
This update fixes an error that could occur when users edited the body text of a social post. It helps keep social post editing stable and prevents interruptions while composing or updating content.
Original PR description
Bug === Since https://github.com/odoo/odoo/commit/059ac6523aae20257811b2d49872bf9e66d29266 , 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
This fixes an issue where directional icons were not mirrored for right-to-left language users. The change improves visual consistency and usability for customers using languages such as Arabic or Hebrew.
Original PR description
__Problem__
In RTL, the directional icons listed in `$oi-custom-rtl-icons` and
`$ms-rtl-icons` are not mirrored.
__Reason__
In `icons.scss`, the generated selectors omit `&`, so
`#{$rtl-selectors}` compiles to `.o_rtl .oi [data-icon="..."]`, a
descendant selector matching nothing instead of the icon element.
Caused by: odoo/odoo@1fb6d5825b
__Fix__
Prefix each generated selector with `&`.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…
### 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
Sale order templates no longer reference an outdated display component for line descriptions. This prevents potential display or editing issues while keeping the existing behavior for sections, notes, and product lines unchanged.
Original PR description
This commit removes the use of the `section_and_note_text` widget on the `name` field of sale order template lines. The use of widget was introduced in 2097904d681dc77a69e75a6f91abf2836da17b1a but the widget itself was removed in 737860187c9a369099eaffff5d1db1dc0ef6a243. Since the `name` field is always rendered using a `TextField`, regardless of whether the line is a section, note, or product line, the `section_and_note_text` widget is no longer needed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website shop add-to-cart button is now truly disabled when unavailable, rather than only appearing disabled. This prevents shoppers from selecting it with a keyboard and accidentally adding products when the action should not be available.
Original PR description
The "Add to cart" button had no disabled attribute, only a class name. It was possible to focus the button by keyboard and click on it by pressing Enter. Now, add_to_cart button has a disabled attribute when it is disabled, which prevents users for focusing it with their keyboard. Task-6009931
The recycle records list now displays the actual record ID in the ID column instead of repeating the record name. This removes confusion for users reviewing recycled records while keeping the row click behavior unchanged.
Original PR description
In the recycle records list, the "ID" column showed the name of the record instead of its ID, repeating what the Record Name column already displayed. This appeared when res_id became a reference field, as those fields are shown as a link to the record by default. The column shows the record ID again, as before. Clicking a row still opens the original record. task-6462808 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
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 website test that could fail depending on which website-related apps were installed. The change makes the test target the intended website snippet area more precisely, improving reliability without changing customer-facing behavior.
Original PR description
Selector added in [1] wasn't specific enough because in some cases it targeted both normal and inner snippets. It checked to see that the last draggable snippet was the "Debug" group, but in cases when the selector matched 2 elements it naturally failed. It matched 2 elements when we had only website installed, as when we also had website_sale installed, in the "inner content" snippets the last child would be a disabled payment snippet, as it couldn't be dropped to the present popup. We fix this by targeting only the last child of the `#snippet_groups` snippets. [1]: https://github.com/odoo/odoo/commit/ec117d700345152132a685c470309127df460be0 runbot-946264
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-prSales order screens now use shorter labels for stacked fields so columns no longer become unnecessarily wide. This makes order lines easier to scan and returns the layout closer to its previous compact size.
Original PR description
The addition of stacked fields made that the width of some columns in the so to be too big. That's why now, instead of the full label, we use abbreviations as labels in stacked fields. Also, we managed to bring the columns to their initial size by deleting the width options.
Website 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
This fixes an issue where Chilean invoice and document numbering could restart from the first number instead of continuing the correct sequence. The correction helps prevent duplicate or incorrect numbering for companies using the Chilean localization.
Original PR description
The recent changes in #282652 rewrote _get_last_sequence_domain to return a SQL object instead of tuple. This turned named params into positional ones. In `l10n_cl` the parameters' orders were kept the same calling so company_id and l10n_latam_document_type_id ended up swapped against the placeholders they filled. This leads to every Chilean numbering query matching nothing and always falling back to first number. task-none
This fix prevents some Odoo interface actions from failing when users interact with the page while parts of it are still loading. It adds safeguards so early clicks or keyboard actions do not trigger errors, improving stability in the website builder and general web interface.
Original PR description
useListener (unlike useExternalListener) attaches its DOM listener during setup(), before the component mounts. When setup() has an async gap (onWillStart awaiting an RPC), these callbacks could fire before mount and dereference refs/state that only exist after onMounted, throwing a TypeError. PR [1] converted a lot of useExternalListener into useListener. This commit adds a safeguard in some of those useListener callbacks that can crash if called too early. [1] https://github.com/odoo/odoo/pull/269501/ 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 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
In Point of Sale, the order details popup now closes automatically when a user chooses to edit a payment. This prevents the popup from blocking the payment screen, making the checkout correction flow clearer and less confusing for staff.
Original PR description
Steps to reproduce: ----------- - Validate an order, then open it from the ticket screen - Open the order details popup, click "Edit Payment" - Redirected to PaymentScreen, but the order details popup stays open on top of it Cause: --------- OrderDetailsDialog (opened via the dialog service) and PaymentScreen (opened via pos.navigate) are two separate stacks. Navigating to PaymentScreen does not close the dialog. Fix: -------------- Call dialog.closeAll() before pos.editPayment(order) in the editPayment callback passed to OrderDetailsDialog, so the dialog closes before navigating to PaymentScreen. task-6463084 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283266 Forward-Port-Of: odoo/odoo#281960
Website editors can now directly edit more parts of mega menu templates, such as footer areas and logo containers. This fixes a limitation in the website builder and makes menu customization smoother without needing technical workarounds.
Original PR description
### Issue: Some elements in mega menu templates are not editable inline in the website builder. ### Steps to reproduce: - Go to Website > Site > Menu Editor and add a mega menu item. - Edit the mega menu and set its template (e.g. 'Thumbnails' or 'Logos'). - Try to inline edit certain sections (e.g. footer or logos container). ### Reason: `BuilderContentEditablePlugin` does not apply `contenteditable="true"` to these elements because they do not match any of the selectors defined in `content_editable_selectors`. ### Fix: Add missing element classes to `content_editable_selectors` so that these elements become editable inline. task-[6116253](https://www.odoo.com/odoo/project/974/tasks/6116253) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283975 Forward-Port-Of: odoo/odoo#263021
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
Opening the command palette with rapid clicks no longer causes an error. This makes the search experience more reliable for users who double-click or interact quickly with the sidebar.
Original PR description
Steps to reproduce: 1. Open Knowledge. 2. From the sidebar, double-click the Search button. 3. Observe the traceback. Cause: Rapid interactions, such as double-clicks or fast consecutive clicks, can trigger the outside-click handler while the component's DOM reference is not yet available. In this case, `this.root()` returns `undefined`, and calling `.contains()` on it raises a traceback. Fix: Guard the root element before calling `.contains()` to ensure the element is available before accessing it.
This update corrects how Odoo detects when the email queue manager is running as a scheduled job, so progress is recorded as intended. It also adds clearer logging of the email sending limit to help support teams investigate silent email queue failures, especially those related to memory limits.
Original PR description
The changes introduced by https://github.com/odoo/odoo/commit/19d5367862528979abdcd411095f18d36bdbe7b8 aimed at aligning the mailing cron job logic with the new `_commit_progress` system. While doing…
The changes introduced by https://github.com/odoo/odoo/commit/19d5367862528979abdcd411095f18d36bdbe7b8 aimed at aligning the mailing cron job logic with the new `_commit_progress` system.
While doing so, it accidentally added an if condition based on `self.env.get('ir_cron')`, which will always return False and never run the progress commit as intended.
To address this, in this PR:
- we change the condition to `if self.env.context.get('cron_id'):`, the cron_id context variable being set when the method was called from a scheduled action
- additionally we take the occassion to add an info log that outputs the computed send limit at the time the method was triggered. This will make it easier to investigate the logs ad-hoc in situations where the "Mail: Email Queue Manager" cron job fails silently because of a memory limit error. A high send limit (batch_size) increases the chances of memory errors proportionally. Knowing what the exact sending limit was at a given point in time makes investigation easier when trying to build a sequence of past events that could explain issues related to email sending.
OPW-6396087
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#283402
Forward-Port-Of: odoo/odoo#282892This 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
This fix updates the Mail module to use the current progress-tracking method when processing outgoing messages. It prevents unnecessary warning tracebacks from appearing in server logs during automated mail queue processing, making monitoring cleaner without changing user-facing behavior.
Original PR description
Since 19.0 `_notify_progress`` is deprecated in favor of `_commit_progress``. See: https://github.com/odoo/odoo/commit/ee337934f9885834d95592946f435c6e1c8ef970 Currently, the mail compose wizard still calls an explicit _notify_progress followed by an explicit commit. This leads to warning tracebacks being dumped into the server logs (for example everytime the "Mail Marketing: Process queue" cron runs). We replace it with an equivalent `_commit_progress` call, which should log the progress and implicitly take care of the cursor commit. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282926
Credit card and cash journal statement lists can now open individual statements in form view. This fixes a navigation issue that prevented users from reviewing statement details directly from the accounting dashboard.
Original PR description
Issue: When opening the credit card statements list view from clicking the "Statements" button in the accounting dashboard of a credit card journal, the resulting list view does not allow clicking on any of the items to enter the form view Steps to reproduce: 1. Create a credit card journal and some credit card statements 2. Go to the accounting dashboard, and click on the button with three dots to the upper right of the credit card journal card and click "Statements" 3. Try to click on any of the statements in the list view and it won’t open any of them Cause: The window action for credit card journals (action_credit_statement_tree) was missing the form view in the view_mode Solution: Add form to the view_mode of action_credit_statement_tree. The cash journal bank statements window action (action_view_bank_statement_tree) was also missing the form view, so it was added as well opw-6449315 Forward-Port-Of: odoo/odoo#282816
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
The VoIP softphone now updates agenda groups, call history labels, and due-date colours automatically when a user leaves it open overnight. This prevents outdated “Today” or “Yesterday” information from staying on screen and helps users see accurate call and task timing.
Original PR description
Enterprise counterpart of "[FIX] mail: refresh what derives from today at midnight", which explains why a rendered value cannot read the clock. Before this commit, a softphone left open across midnight keeps grouping its agenda and its call history under "Today" and "Yesterday", keeps the colour of yesterday's due date, and keeps labelling a call "Today, 5:00 PM". This commit reads the day off the store in the agenda, the history and the call date widget. https://github.com/odoo/odoo/pull/282991
The data cleaning lists now show the actual record ID in the ID column instead of duplicating the record name. This restores the expected view and helps users distinguish records more clearly while keeping row clicks linked to the original record.
Original PR description
In the deduplication and field cleaning lists, the "ID" column showed the name of the record instead of its ID, repeating what the Record Name column already displayed. This appeared when res_id became a reference field, as those fields are shown as a link to the record by default. The column shows the record ID again, as before. Clicking a row still opens the original record. task-6462808
Fixes an issue where Sign fields connected through related records were not recognized properly, causing values to appear without the correct formatting. This helps signed documents show linked information more accurately and consistently for users.
Original PR description
A sign item type can be linked to a field through a relation. In that case the field definition was looked up using the whole path as a field name of the base model, which never matches, so no definition was found and the value was filled as is, without any formatting based on the field type. Resolve the path first so the definition is fetched on its last model. task-6454994
This fixes a crash in the Journal Audit report and its Italian Libro Giornale variant when optional review information is not available. Users can now open and use these reports reliably even when that review column is not configured.
Original PR description
'to_review' is an optional custom line key use by the Journal Audit report. It is set using the value of a dedicated report column, which contains a count of db rows, and is therefore always an integer. In l10n_it_reports, a variant of the Journal Audit report is introduced, the Libro Giornale. That report does not define a column to compute 'to_review'. Because of that, the root report's _custom_line_postprocessor doesn't assign any value to the key in the line dict and on client side, when trying to evalute the to_review signal, we try to call undefined as a function, causing a crash.
This fix prevents the VoIP Call Flow editor from repeatedly reacting to its own updates, which could cause unstable behavior when schedules are changed. It restores the intended safeguards so call flow changes are handled reliably without affecting the wider VoIP experience.
Original PR description
OWL3's useEffect takes one argument, so the OWL2 deps callback is dropped: extendSchedule() could re-enter on the record mutations it had just caused. Came in with the Call Flow editor, odoo/enterprise#107700. Effects kept: they do async and imperative model work, not derivation, so useOnChange restores all three declared dependency lists verbatim.
The automated self-order confirmation check was updated to match the revised payment screen layout. This keeps internal quality checks aligned with the current customer payment experience and helps prevent false test failures.
Original PR description
Before this commit, the self-order confirmation tour asserted the amount-due copy "Pay $ 2.53 at the counter" as a single string. This commit fixes the now-failing step to match the community payment processing screens small redesign, which splits that into a "To pay at the counter" label and a separate amount, by asserting the amount span directly. task-6341668 requires: https://github.com/odoo/odoo/pull/276232
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
Users can now create WhatsApp templates directly while configuring server actions, reducing setup friction. This fixes an interface limitation and makes WhatsApp automation easier to manage.
Original PR description
Allow creation of whatsapp templates via the many2one in action server. part-of-task-4976562
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#126463The update makes an automated check for German point-of-sale certification wait until the product screen is fully ready before continuing. This reduces random test failures in validation systems, helping keep releases and related changes from being blocked by unrelated instability.
Original PR description
we face this error when running tour `FiskalyTour` with linked pr (which is completely independent of this module) and should not fail, but this can be considered as non-deterministic. waiting/confirming that product-screen is shown, before making the next move, solves the issue. build link: https://runbot.odoo.com/runbot/batch/2696526/build/121430872?debug=1 Forward-Port-Of: odoo/enterprise#128733 Forward-Port-Of: odoo/enterprise#127902
This 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
A display issue in the bank reconciliation quick create form has been corrected after a recent interface styling change. The fields now use the full available width, making the form easier and more reliable to use.
Original PR description
There was a change in the css since owl3, the quick create was impacted. By adding w-100 to the two fields, the problem is solved. no task id Forward-Port-Of: odoo/enterprise#123293
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.