Wednesday, November 12, 2025
30 changes · 19.0
Enhancements to existing features
The point-of-sale receipt step is being streamlined by removing the separate receipt screen and using the feedback screen instead. This keeps the customer journey simpler while preserving existing features and integrations, so businesses should see the same outcomes with fewer steps.
Original PR description
pos*: l10n_br_edi_pos, l10n_it_pos, whatsapp_pos This commit aims at removing the receipt screen and replacing it with the feedback screen. Of course, the feedback screen needs some adaptations done in this commit to keep every existing feature. task-id: 5149815
The point-of-sale checkout flow has been simplified by replacing the separate receipt screen with the feedback screen. This keeps the same receipt-related features while reducing an extra step for staff and making the end-of-sale experience more consistent across POS setups.
Original PR description
pos*: point_of_sale, pos_restaurant This commit aims at removing the receipt screen and replacing it with the feedback screen. Of course, the feedback screen needs some adaptations done in this commit to keep every existing feature. task-id: 5149815 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update speeds up how tax returns are generated and refreshed, making the related accounting screens and setup wizard respond faster. It also fixes a case where manually created draft returns could be incorrectly removed before being posted.
Original PR description
- batched _compute_company_ids on returns - batched return to unlink in _generate_or_refresh_all_returns - removed redondant call to _generate_or_refresh_all_returns in…
- batched _compute_company_ids on returns - batched return to unlink in _generate_or_refresh_all_returns - removed redondant call to _generate_or_refresh_all_returns in action_save_onboarding_fiscal_year since we want to call it only when a value is changed and that's already handled in the write on the company. - batched _is_available_for on reports - make only one write on the company (and one call to _generate_or_refresh_all_returns) when writing or create the fiscal year wizard. - dont delete return created manually with a date before the date of the account_opening_date and not yet posted. Detected from runbot error: https://runbot.odoo.com/odoo/runbot.build.error/231463 A small workaround is needed on the company when writing the changes from the fiscal year wizard. This is because related fields are writen one by one, which then trigger multiple times _generate_or_refresh_all_returns. To prevent this, we are batching all the write on the company from the fiscal year wizard in one write. The opening_date need to be handled separatly since it's not a related field but still need to be writen on the company, if removed from the vals during the create it's then not possible to save the wizard anymore. Also fixed a bug where the returns manually created before the account_opening_date would be deleted if they were not posted before the next call to _try_create_returns_for_fiscal_year. **Detailed Explanation** We can see the tour being broken when trying to save on the wizard: <img width="1366" height="768" alt="image" src="https://github.com/user-attachments/assets/9443251c-aee1-4fbe-be2f-27c11bcbb77d" /> So we can do a flamegraph to take a look at what's happening on that database during that time and we can see 2 majors time uses, a call to `_generate_or_refresh_all_returns` triggered by a write on the wizard and a call to `action_save_onboarding_fiscal_year` <img width="1396" height="855" alt="image" src="https://github.com/user-attachments/assets/a9d310da-2787-4806-951d-e50b8c1da2a8" /> The first call to `_generate_or_refresh_all_returns` took about 7.8s, the second one took about 1.1s First, we can see a lot of `_compute_company_ids` calls, this is because we have `precompute=True` on this field due to it being needed in the different access rules. Since all the returns that are created have similar main company, tax unit and return type, we can easily batch them to only call `_get_company_ids` once for all the returns that will be created. Resulting in the following flamegraph: <img width="1422" height="866" alt="image" src="https://github.com/user-attachments/assets/c52c88c7-0263-44fb-a16c-52456673dc92" /> The first call to `_generate_or_refresh_all_returns` took about 0.8s, the second one took about 1.2s Another little change we can do is to remove the call to `_generate_or_refresh_all_returns` during `action_save_onboarding_fiscal_year` and adding the forced_date from the first one to the second one. <img width="1294" height="844" alt="image" src="https://github.com/user-attachments/assets/7ad55d06-ecd4-4957-b514-71fffa6de00c" /> We now end up with one call to `_generate_or_refresh_all_returns` that takes 1.4s BUT, we can still do better. We can see that all we did previously was only do to one thing less. The "real" problem was the many search calls done in `_is_available_for` during the `_init_options_variants`. <img width="1268" height="693" alt="image" src="https://github.com/user-attachments/assets/ebae398d-dfdd-4c1e-99ac-44f25e5875e7" /> After the final change, we are down to 0.9s ! One thing to keep in mind, all those flamegraph were done on a dump of a database from a nightly test, which had many companies created as well as **every** modules installed, which means every return types, reports, ... This means those performance improvements wont be as useful on small databases.
Resolved issues and error corrections
The follow-up report now correctly ignores invoice lines marked as "No Follow-Up" when calculating a partner’s balance. This prevents partners from being incorrectly shown as needing no action when they still have overdue items that should be chased.
Original PR description
### Issue: Have a partner with an overdue invoice and a credit note with an amount greater than the invoice but excluded from follow-ups. This partner will have a follow-up status of…
### Issue: Have a partner with an overdue invoice and a credit note with an amount greater than the invoice but excluded from follow-ups. This partner will have a follow-up status of `no_action_needed` where it should be `in_need_of_action`. ### Steps to reproduce: - Create an overdue invoice for a new partner - Create a credit note for this partner with an amount greater than the invoice - Accounting > Reporting > Partner Ledger - Change the report to 'Follow-up Report' - Unfold the new partner and tick 'No Follow-Up' for the credit note line - Go to the partner form view, under the 'Accounting' page - The status is 'No action needed' ### Cause: The query responsible for the computation of the follow-up status does not consider the `no_followup` option to compute the balance of the partner. So the partner has a negative balance and the line `WHEN partner.balance <= 0 THEN 'no_action_needed'` gives the partner the status `no_action_needed`. ### Solution: Only consider lines with `no_followup = False` in the computation of the partner balance. Now when a partner only has lines with `no_followup = True` the query will not return anything, so the test method `assertPartnerFollowup()` needed to be adapted. opw-5170038
A bug that caused a server error when switching on eCommerce Categories in the website mega menu has been fixed. The editor now correctly finds the mega menu content even when the first element is not the expected one, preventing the traceback and making the customization work reliably.
Original PR description
A traceback would occur when clicking the "eCommerce Categories" toggle in the mega menu's style options. Steps to reproduce: 1. Go to the Website editor. 2. Add a mega menu to the page header. 3. Edit and Click on the mega menu's 4. In the sidebar, click the "eCommerce Categories" toggle. -> Traceback. Cause: When loading it was trying to find a specific class name (starting with `s_mega_menu_`) to identify the snippet. It was hardcoded to only look at the `firstElementChild` of the snippet's container. This assumption was too rigid. If the first element was a `<p>` tag or another element without the required class, the code would fail to find it. This resulted in an `undefined` value being sent to the server, causing the traceback. Solution: Use `querySelector` to search for any element with a class name containing `s_mega_menu_`. opw-5245777 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When a guest joins a meeting and changes their name on the welcome page, the updated name now appears immediately in the participant list. This improves clarity for meeting hosts and helps everyone identify guests more easily.
Original PR description
**Steps to Reproduce:** - Login with Admin, start a meeting, open the member list. - Join the meeting with a guest, using the invite link. - Change the guest name from the welcome page. - Admin member list doesn't show updated guest name. **Current behavior before PR:** Before this PR, the guest appeared as `Guest` in the member list even after updating their name on the welcome page. **Desired behavior after PR is merged:** This PR ensures the guest name is updated and displayed instantly upon joining, providing a smoother and more consistent experience. task-[5062702](https://www.odoo.com/odoo/project/1519/tasks/5062702) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234299
This fix restores the ability to tap an order line to select it in the product screen when the IoT scale certification module is installed. It ensures the long-press configurator feature works without blocking normal line selection, improving usability at the point of sale.
Original PR description
Task: [5163235](https://www.odoo.com/odoo/project/1737/tasks/5163235) --- In the product screen, pressing an orderline was supposed to select this line and a long press was supposed to open the Configurator popup. However, since the feature of the long press, if we install the module `l10n_eu_iot_scale_cert`, pressing an orderline does not select it anymore. This was due to the fact that a `t-ref` was added in the orderline template and that in the `l10n_eu_iot_scale_cert` module, we were overriding this template completely. Forward-Port-Of: odoo/enterprise#98886 Forward-Port-Of: odoo/enterprise#96980
This change lets users cancel a duplicate payroll slip even when it shares work entries with another slip. It prevents unrelated work entries from being reset, reducing disruption and making payroll corrections safer and easier.
Original PR description
previous behavior: - Cancelling duplicate payslips wasn't possible because they had the same work entries linked current behavior: - Allows to cancel a duplicate payslip without affecting the linked work entries - Work entries are only set to draft when they are linked to one payslip that is being cancelled - added `test_duplicate_payslips_cancellation` task-id: 5075882 Forward-Port-Of: odoo/enterprise#94236
Scanning a self-invoicing QR code now sends users directly to the ticket validation screen, instead of opening a page with incomplete information. If the customer is already registered, it can go straight to the invoice, reducing friction and avoiding failed or confusing follow-up steps.
Original PR description
Before: QR scan(self invoicing) redirected to /pos/ticket with pre-filled data but missing ticket code. After: Now directly redirects to the validation screen or invoice if customer is already registered. taskID-4777138
This update restores menu mode in self-ordering so customers can browse and order as expected. It prevents disruptions in the ordering experience and helps ensure orders can be placed smoothly on mobile and kiosk flows.
Original PR description
Menu mode was broken in self ordering. This commit fix it. Forward-Port-Of: odoo/odoo#234460 Forward-Port-Of: odoo/odoo#232503
This change prevents an error when users paste a Vimeo link into the Knowledge app’s media dialog. It makes the video link handling more robust so the dialog works normally even when the link does not include extra time information.
Original PR description
Steps to reproduce: ------------------------- 1. Install the Knowledge app 2. Open any document and use `/media` to open the media dialog 3. Go to the Videos tab in the dialog 4. In another browser…
Steps to reproduce:
-------------------------
1. Install the Knowledge app
2. Open any document and use `/media` to open the media dialog
3. Go to the Videos tab in the dialog
4. In another browser tab, open the Vimeo website
5. Copy any Vimeo video link and paste it into the dialog
Observation:
-------------------------
When pasting a Vimeo link, a traceback occurs:
```
TypeError: Cannot read properties of undefined (reading 'match')
at EmbeddedVideoSelector.parseTimeToSeconds
```
Issue:
-------------------------
In the following function,
https://github.com/odoo/odoo/blob/b5ed2d5a3e4ac9379ed15549dd9c8e08547181bb/addons/html_editor/static/src/main/media/media_dialog/video_selector.js#L350-L353 This happens because the code splits the Vimeo URL using `#t`. If the URL does not contain `#t`, the result is undefined, which is then passed to the `parseTimeToSeconds` function.
Solution:
-------------------------
Added optional chain operator in `parseTimeToSeconds` for safe validation of
`value` before calling `.match()`
opw-5221403A layout issue in the Discuss app could cause the page to overflow horizontally when opening or closing the call sidebar during a call. This update adjusts the call layout so the main view resizes correctly, keeping the interface stable and preventing visual overlap.
Original PR description
Before this commit, when in a discuss call in the Discuss app with sidebar not compact and a right panel open, click on Discuss sidebar would overflow horizontally the UI. This happens because the rearrange of tiles of the discuss call grid would be triggered from sidebar toggle state change, but the rearrange of tiles was mistakenly coded to preserve the height of main tile. This is a problem with discuss call sidebar because while the overall height of call view should stay unchanged, the main card must have its height reduced to compensate with discuss call sidebar when shown. This commit fixes the issue by resetting temporarily the height of call card tile in `arrangeTiles()`, so that it takes into account when it has to adapt its height. Before  After 
This change corrects a field reference in stock accounting so the system uses the company currency instead of an invalid currency field. It prevents errors caused by the wrong field being used and helps stock valuation work as expected.
Original PR description
commit 9c63ac283b89807c23a8a1934eef8074a312c36d Introduced a bug since it uses the field `currency_id` instead of the correct field `company_currency_id` 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 change prevents a table placed inside another table from expanding beyond its parent cell when resized. It keeps the table within bounds so users can continue editing it normally.
Original PR description
**Current behavior before PR:** - When a table was created inside another table, resizing the inner table could cause it to overflow its parent cell, making it uneditable. **Desired behavior after PR is merged:** - The inner table no longer overflows its parent cell when resized, ensuring it remains editable. task-5216916 Forward-Port-Of: odoo/odoo#233554
This change fixes an error that could happen when users tried to edit certain website pages, such as appointments pages. It improves the editing experience by preventing the editor from crashing on text elements, so pages can be opened and edited normally.
Original PR description
To reproduce: ============= - with website appointments installed go to appointments page - try to edit the page -> error Problem: ======== when entering edit mode, we call `selection_blocker_predicates` on editable nodes which will call `node.hasAttribute` internally. However, some nodes are text nodes and thus do not have this method, leading to an error. Solution: ========= `isBlock` method checks several things on the node, including if it's a text node. so swapping the order of the conditions will fix the problem. opw-5239754 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Uploading an invalid or encrypted PDF in Sign no longer causes an error screen. The system now checks the file first and safely rejects unreadable documents, improving reliability for users working with signed documents and templates.
Original PR description
Currently, an error occurs when trying to upload an encrypted/invalid document in the Sign Documents. **Steps to reproduce:** 1. Install **Sign** module. 2. Try to upload the encrypted PDF in Sign Document or templates. **Sample files:** https://drive.google.com/drive/folders/1MkiFRgJOlv2zc6ZW3SJYnMwHZYy9CFtX?usp=drive_link **Errors:** ``` DependencyError - PyCryptodome is required for AES algorithm UnicodeDecodeError - 'utf-8' codec can't decode byte 0xa4 in position 0: invalid start byte ``` **Cause:** The `flatten_pdf` function calls `PdfFileReader`, which raises an error if the file is encrypted or cannot be read/decrypted properly. Also, adding AES encrypted document in already uploaded valid document will triggers the same error. **Fix:** This commit prevents a traceback when uploading invalid or encrypted PDF files by validating the PDF data beforehand. sentry-6913657420
This fix ensures that journals excluded from a Multi-Ledger remain excluded even after they are archived. As a result, financial reports such as Profit and Loss will no longer include entries from journals that were meant to be left out.
Original PR description
A journal is still excluded from the ledger even if it is archived. To reproduce: * create a new journal * create a journal entry impacting the P&L in that journal * create a Multi-Ledger (journal group) excluding this journal * archive the journal * open the P&L The journal entry is impacting the report, because the journal is not excluded. task-5251383
This update fixes how tax return reports are handled when a country has more than one report type. It prevents duplicate or incorrect return content by ensuring each closing entry uses only the relevant tax data, and it adjusts some reports so they no longer generate an unnecessary closing entry.
Original PR description
It's possible for different tax reports to exist in the same country, each with its own return type. However, this is an issue when they aren't configured to generate closing entries with distinct contents, since each of them will then repeat the content of the other. To fix this, when it's legitimate to make multiple closing entries, we make sure the closing entry only considers the tax move lines linked to the report's tax tags. If multiple reports must generate the same closing entry (typically because one of them is a simplified version of the other), we disable the generation of the return for one of them. Some reports also didn't need to generate a closing entry and were switched to a 'review_submit' state. task-5123564 Forward-Port-Of: odoo/enterprise#98973 Forward-Port-Of: odoo/enterprise#98158
Pivots inserted into spreadsheets now keep the same date-based sorting as in the web pivot view. This fixes an issue where date and date-time columns could lose their order because their values were not normalized correctly.
Original PR description
If on the web pivot view we create a pivot with a date/dateTime field in the columns, and sort on one of these columns, the resulting pivot when inserted in a spreadsheet isn't sorted. This was because we didn't normalize the date values in the pivot `sortedColumn`, and we had UTC timestamps `2023-01-01 00:00:00` instead of normalized values `01/2023`. Task: [3575465](https://www.odoo.com/web#id=3575465&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) Forward-Port-Of: odoo/enterprise#99203 Forward-Port-Of: odoo/enterprise#96508
Follow-up reminder emails now keep the invoice attachment when invoices are set to be included. This fixes an issue where the system was accidentally hiding those attachments, so customers receive the full reminder message with the invoice included.
Original PR description
### Issue: The invoices supposed to be sent with follow-ups when the option `join_invoices` is tick are not sent. ### Steps to reproduce: - Install "account_followup" - Create a new partner - Create…
### Issue: The invoices supposed to be sent with follow-ups when the option `join_invoices` is tick are not sent. ### Steps to reproduce: - Install "account_followup" - Create a new partner - Create an invoice for this partner with a due date in the past, confirm and send - Go on the partner form view, under the "Accounting" it should be in the state "In need of action" - Click "Send", the wizard pops up with the invoice attachment - Click "Send", the message does have the invoice attachment, only the report ### Cause: The attachment in linked to the wizard in database but when doing a read, the domain is appended with `'res_field', '=', False` by these lines: https://github.com/odoo/odoo/blob/f8f72b15598576f5870e49879e96fc5c127a6100/odoo/addons/base/models/ir_attachment.py#L598-L603 But the invoices attachments have res_field set to `invoice_pdf_report_file` so they are filtered out. The purpose of adding the new leaf to the domain is to filter out attachments that we are not searching for specifically. As they are linked to a specific field (`res_field`), if we don't search on this field, we are not supposed to see them. With the `followup_manual_reminder` wizard, we are linking attachments having a `res_field` to `account_move.invoice_pdf_report_file` to a new field: `followup_manual_reminder.attachment_ids`. So `'res_field', '=', False` should not be added. ### Solution: The problematic fields are all `Many2Many` fields to `ir.attachment` and since [this commit](https://github.com/odoo/enterprise/commit/fd4fcb1bd8764dbde1c8b3295623dd020c882a60) these fields have `bypass_search_access=True`. So the fix consist of not adding the domain `'res_field', '=', False` when `bypass_access` is True. opw-5164456
Live chat on mobile devices now keeps the message field at a readable size without triggering the browser’s automatic zoom. This prevents the send button from being hidden and makes it easier for visitors to type and send messages smoothly.
Original PR description
Before this commit, when using livechat for visitors on mobile devices, click on input would zoom on input of about 115%. This zoom would hide send button at the very end of composer input, and would…
Before this commit, when using livechat for visitors on mobile devices, click on input would zoom on input of about 115%. This zoom would hide send button at the very end of composer input, and would force users to pinch-to-unzoom, making the UX quite poor. This problem happens because mobile devices have an auto-zoom feature that is triggered when font-size is below 16px. The discuss UI is designed with 14px font size (web client font size), and since 14px < 16px, it zooms on input focus to about 115%. This commit fixes the issue by using a font-size of 16px specifically for livechat visitor on mobile devices, so that this doesn't auto-zoom. Note that this problem doesn't happen on the web client even though this uses a font-size of 14px because it specifically disable the autozoom feature: https://github.com/odoo/odoo/blob/17.0/addons/web/views/webclient_templates.xml#L250 This solution is not practical for livechat, for which it has to work on any external website. opw-5229076 Before <img width="199" height="431" alt="after" src="https://github.com/user-attachments/assets/cc2f8e04-bde7-4eeb-84d5-b2efa2763490" /> After <img width="199" height="431" alt="before" src="https://github.com/user-attachments/assets/6c6679fc-9c16-40e7-ab6f-21540d20d59d" /> Forward-Port-Of: odoo/odoo#235182 Forward-Port-Of: odoo/odoo#234967
The website editor could crash when users tried to edit the appointment booking page. This update prevents the error by handling non-page elements safely, so editing the page works normally again.
Original PR description
**Steps to reproduce:** - Install website_appointment_sale with demo data - Start booking an appointment and stop at the `Date & Time` selection page - Open the `website editor` and click the `edit`…
**Steps to reproduce:**
- Install website_appointment_sale with demo data
- Start booking an appointment and stop at the `Date & Time` selection page
- Open the `website editor` and click the `edit` option
- A traceback occurs
**Issue:**
- A traceback occurs when trying to edit the page,
Error:
`TypeError: blocker.hasAttribute is not a function
at selection_blocker_predicates`
**Cause:**
- The `selection_blocker_predicates` function assumed every `blocker` was an Element
and called `blocker.hasAttribute(...)`. When a non-element node (text, comment, or object)
was encountered, the call raised a 'TypeError'.
<img width="778" height="177" alt="image" src="https://github.com/user-attachments/assets/7ef14d01-56e0-45b7-a39e-3e9fb6a4c6ce" />
> nodeType = 3 then it’s a `text node`
https://github.com/odoo/odoo/blob/700fac2532d2de6abc6f87e30a5b056dcfc109d1/addons/html_editor/static/src/main/selection_placeholder_plugin.js#L39-L45
**Solution:**
- Make the function defensive by checking that `blocker` is an instance of `Element`
- before accessing DOM methods. Non-element nodes are now safely check.
---
opw : 5241222
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis change lets employees and other users read work entries even if they are not attendance managers. It removes an access-rights error that could block normal viewing of work entry information, improving day-to-day usability.
Original PR description
When we try to read the work entries, we've got an access rights error if we are not attendance manager. As we are still supposed to read the work entries, we get the attendance interval in sudo --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The fiscal year setup wizard now correctly applies changes to the company even when the wizard starts with default values. This reduces the risk of duplicate updates and makes the setup flow more reliable in more scenarios.
Original PR description
When writing value with the wizard, we wrote the value of related field of the company to prevent multiple write from happening. Now, we handle the write too in case the wizard is created with default value instead of created beforehand. It's also now possible to specify the fields that are to be written to handle more cases in overrides. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change prevents Spreadsheet from crashing when freezing or sharing a view that includes a boolean global filter. It ensures Excel exports handle empty filter values safely, improving reliability for users working with shared spreadsheets.
Original PR description
The method `getFilterDisplayValue` would not handled `undefined` values for boolean global filters, causing crashes when exporting to Excel. Task: [5188932](https://www.odoo.com/web#id=5188932&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235123 Forward-Port-Of: odoo/odoo#232784