Daily updates from Odoo
Saturday, July 11, 2026
37 changes · master
New functionality added to Odoo
Odoo can now recognize and contact WhatsApp users through business-scoped user IDs when phone numbers are not shared. This helps businesses continue conversations reliably and match contacts more accurately across WhatsApp and Odoo.
Original PR description
Add support for whatsapp business-scoped user ids as outline in the [documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/business-scoped-user-ids) for their introduction this June. This effectively adds a table mapping BSUID to contacts to enable contacting users who contact the business directly, as the business will now not necessarily be provided with their number. Additionally the “whatsapp id”, i.e. the canonical form of the phone number as stored in whatsapp, is stored to help better match contacts regardless of formatting details in odoo and whatsapp. task-5476552 Forward-Port-Of: odoo/enterprise#117782
Enhancements to existing features
VoIP call lists now offer an easier-to-understand grouping option that shows friendly labels such as Contact or Task instead of technical model names. The related document ID field was also clarified in custom searches, while keeping the main view label simple for everyday users.
Original PR description
Steps that were improved: - VoIP calls list view - Search -> Group by -> Custom Group -> "Related Document Model" - Grouping appears with values like "res.partner", "project.task", etc => That is fine but it would be better to have "Contact", "Task", etc => There is now a "Logged On" custom group that is there for that and easier to find. Also renamed "Logged On" m2o reference field to "Logged On (ID)" to have a distinction with the new "Logged On" in custom searches (those custom searches can only be used if you know the exact numeric ID anyway). The view still display "Logged On" as the label of that m2o reference though to appear less technical. task-6234384
Belgian payroll rules now include the updated employment bonus parameters effective 1 July 2026 and 1 September 2026. This helps ensure payslip calculations remain aligned with upcoming Belgian legal payroll requirements.
Original PR description
Update the employment bonus parameters for 1st July 2026 and 1st September 2026. task-6369633 Forward-Port-Of: odoo/enterprise#123566 Forward-Port-Of: odoo/enterprise#123262
Deleting attachments linked to Chilean electronic invoicing and stock documents is now much faster, especially in databases with large volumes of accounting moves and deliveries. This reduces waiting time and improves system responsiveness during cleanup or document management operations.
Original PR description
## The problem Deleting attachments checks foreign key triggers. Lookups in `account_move` and `stock_picking` tables for `ir_attachment` related fields coming from `l10n_cl_edi` overrides were slow due to missing indexes. ## The solution Added needed indexes to optimize triggers' lookups. ## Benchmark Time benchmark (deleting attachments from a customer database with 224K account moves and 204K stock pickings): |# of rows|Time (Before)|Time (After)| |----------|--------------|-------------| 100 | 29s | 16ms 1000 | 285s | 300ms OPW-6331845 Forward-Port-Of: odoo/enterprise#123350 Forward-Port-Of: odoo/enterprise#123252
Databases can now display the status of the Know Your Client procedure as a dedicated KPI. This helps business users quickly understand customer verification progress directly from database information.
Original PR description
Add a new type kyc_status to display the status of the Know Your Client procedure in the databases. Task-id: [6348952](https://www.odoo.com/odoo/project.task/6348952) Forward-Port-Of: odoo/enterprise#122510
The time off planning Gantt view now uses paging and opens at a broader overview scale by default. This should make large leave schedules easier to load, browse, and review for managers and HR teams.
Original PR description
Add paging and default scale as the overview gantt task-6381315 Forward-Port-Of: odoo/enterprise#123936
Resolved issues and error corrections
This fix ensures barcode users cannot add or scan unreserved products when an operation type has extra products disabled. It keeps inventory workflows aligned with configured controls and prevents accidental stock discrepancies after reserved items are completed.
Original PR description
# How to reproduce - Go to Inventory > Settings > Operation Types - Pick any Operation and disable "Allow extra product" - Create a picking for that operation type with atleast one product and click…
# How to reproduce - Go to Inventory > Settings > Operation Types - Pick any Operation and disable "Allow extra product" - Create a picking for that operation type with atleast one product and click on "Mark as Todo" - Go to the Barcode app and find the created picking - Scan all the reserved products - Exit the picking and re-enter # The problem The "Add Product" button is displayed and you can scan unreserved products even tough you sould not be allowed to # Cause of the issue The problem stems from the fact that even with "Allow extra product" disabled, we still allow to add unreserved products for immediate transfers (created directly in the barcode app). The issue is that we don't really have a way to distinguish immediate transfers from plannified ones made in the Inventory app. So we try to guess using the `_useReservation` attribute (If it is false, we allow additional products). `_useReservation` is computed as follows : if any move lines from the inital state is not yet picked, set it to true : https://github.com/odoo/enterprise/blob/ca4b369e4fc9f4655574cf1ca71c81faaadc3e88/stock_barcode/static/src/models/barcode_picking_model.js#L43 So in our case, once all the reserved products are scanned, all the initial move lines are picked and our guessing fails. # Proposed Solution Since immediate transfers are never validated and stays in draft mode, guess using the state of the current picking in addition to `useReservation` opw-6231238 Forward-Port-Of: odoo/enterprise#118378
Default website dynamic snippets now use the correct filter references regardless of the order modules were installed. This prevents generated websites and sales pages from showing incorrect or broken dynamic content when installations differ.
Original PR description
Our default dynamic snippets filter ids are set based on the order that we install our modules. This can cause issues if the user installs their modules in a different order. To fix this, we need to update the data-filter-id value to the correct value of the DB. To be able to do this, we also change the regex replacement to use lxml instead since it's much simpler. Lxml part from 799f83575e162eb683cfaebb4eb602ccc1fbe466. Forward-Port-Of: odoo/enterprise#123634 Forward-Port-Of: odoo/enterprise#122671
This fix ensures point-of-sale planning correctly considers all resources when a payment method is not tied to a specific resource. It also limits planning slot selection to the same company as the POS configuration, helping avoid incorrect cross-company availability.
Original PR description
When no resource is linked to a resource payment method, we should take into account all resource which was not done before. This is now done. We also change the filter in python to only look for slots that are part of the same company as the config. Forward-Port-Of: odoo/enterprise#121909
Payroll work entries generated from attendances no longer create duplicate entries when a worked-time leave overlaps a public holiday. This helps ensure employees' payroll days are counted correctly, especially for flexible schedules and sandwich-rule leave scenarios.
Original PR description
Issue: When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day.…
Issue: When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day. Steps to reproduce: - Create an employee with Work Entry Source set to Attendances - Use a flexible working schedule on the employee - Configure a public holiday on a scheduled day with work entry type (Paid time off) - Create a time off type with Count as set to Worked Time - Generate time off for the period so the public holiday entry exists (maybe a day before and a the public holiday and the day after) - Open Payroll > Work Entries (Observe the date of the public holiday will have more than 8h entry) Cause: In `_get_version_work_entries_values()`, calendar leaves are split by `hr_holidays` `time_type` into: - leaves: absences and public holidays - worked_leaves: worked-time time off For attendance-based contracts, both sets were turned into work entries without removing overlap between a public holiday and a worked-time leave on the same period. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L222-L226 For non-flexible calendar: Public holidays and worked-time leaves are both clipped to the static working schedule (e.g. 8h per working day). overlap was kept in both result sets. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L260 For flexible calendar: The one-day intervals are kept as the actual interval (often 00:00-23:59 for a public holiday). The worked-time on that day is schedule-shaped (e.g. 8h). Subtracting intervals on a full-day public holiday left a 16h fragment instead of removing the public holiday entry. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L242-L249 Solution: We need to make regular leaves take priority over worked-time leaves, compute the real regular leave intervals first, then remove those intervals from the worked-time leave intervals before work entries are created: - for fully flexible employees, subtract regular leaves from worked leaves; - for flexible calendars, keep one-day regular leaves as is and subtract them from worked-time leaves - for non-flexible attendance-based calendars, clip regular leaves on the static schedule, then subtract them from worked-time leaves clipped on the same schedule. This means that when a sandwich worked-time leave overlaps a public holiday, the public holiday consumes that period first. The overlapping part is then removed from `real_worked_leaves`, so no second worked-time entry is generated for the same public holiday period. opw-6237163 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#122126 Forward-Port-Of: odoo/enterprise#119530
Fixes an error that could interrupt Belgian tax return setup when validating sales lists involving Northern Ireland customer rules. This helps accounting teams generate returns reliably without unexpected system failures.
Original PR description
…mers Steps to reproduce: - Setup a Belgian company - Make a sale to a French customer in June for example - Setup the tax returns (so that June returns are generated) -> Traceback raised from the check on sales done to customers from North Ireland. Forward-Port-Of: odoo/enterprise#123556
Fixed an issue where expanding a folded Knowledge article could show only favorited child articles while hiding the other children. Users can now reliably see the complete article hierarchy in the sidebar without needing to reload.
Original PR description
The sidebar always loads the user's favorite articles along with the visible ones, so a favorited article is shown as a root of the favorite tree. When that favorite is also a child of a folded…
The sidebar always loads the user's favorite articles along with the visible ones, so a favorited article is shown as a root of the favorite tree. When that favorite is also a child of a folded article, it gets added to its parent's child_ids in the main tree, even though the parent's other children were not fetched. A folded article only gets its favorited children back from get_sidebar_articles, not its whole child set. When the parent is then unfolded, unfold() only read the children from the database when child_ids was empty. The favorited child already filled child_ids, so the call was skipped and the remaining children stayed hidden until the next reload. unfold() now uses a new children_loaded flag instead of the length of child_ids to decide whether to fetch the children. The flag is set once an article's whole child set is loaded: in loadChildren(), and in loadArticles() for the articles that were unfolded, since those come back with all their children. loadChildren() also rebuilds child_ids from the search result so a favorite already loaded is not added twice. The fix lives in the sidebar component because the partial child_ids only exists on the frontend, get_sidebar_articles already returns the right records. Steps to reproduce: 1. Open the Knowledge app 2. Create an article with two child articles 3. Add one of the two children to your favorites with the star icon 4. Open another article that is not under that parent 5. Fold the parent article in the sidebar, then refresh the page 6. Expand the parent article => only the favorited child is shown under the parent, the other child is missing Ticket [link](https://www.odoo.com/odoo/project.task/6186466) opw-6186466 Forward-Port-Of: odoo/enterprise#118804
GSTR-1 spreadsheets now report SEZ invoices issued in foreign currencies using the company currency, INR, instead of the original foreign currency. This helps businesses submit accurate Indian GST return data and avoids mismatches in reported invoice values.
Original PR description
Currently, when generatign GSTR-1 return spreadshee, SEZ invoices issued in a foreign currency are exported with their totals in the foreign currency rather than the company currency (INR) Steps to reproduce: - Create a B2B SEZ invoice in foreign currency - Go to Accounting > Reporting > [India] GST Return periods - Generate the GSTR-1 report for the period Issue: In the resulting spreadsheet, the "Invoice Value" column takes the invoice total in USD rather then INR opw-6292913 Forward-Port-Of: odoo/enterprise#122514 Forward-Port-Of: odoo/enterprise#121157
Fixed the warning shown when one employee or resource does not have the required role for a shift. The message now uses correct singular grammar, making scheduling alerts clearer and more professional.
Original PR description
Currently, when a (or multiple) resource(s) do not have the role for a particular shift, a warning is displayed. However, in the case where only one resource does not have the correct role, the following warning was displayed, "resource_name don't have the required role for this shift", instead of "doesn't". task-6153932 Forward-Port-Of: odoo/enterprise#120899
Foreign EU VAT invoices over 10,000 CZK are now placed in the correct section of the Czech VAT control statement. This prevents non-domestic transactions from being incorrectly reported as domestic, improving compliance accuracy.
Original PR description
With l10n_cz company: - Create an invoice for a partner with a foreign vat (EU) with an amount greater than 10000 CZ and a 21% tax. In the vat control statement of the tax report, the move is classified under A4. But the section A4 should only contain move with domestic vat opw-6268506 Forward-Port-Of: odoo/enterprise#120002
AI-related screens now display better on smaller devices, with cleaner layouts for agent profiles, composer cards, and skill forms. This makes the AI tools easier to read and use on phones and tablets by reducing wasted space and positioning key information more clearly.
Original PR description
This commit improves the user experience of the AI modules on smaller screens by fixing several views for mobile devices. The changes include: - Adapt the AI agent form view to follow the Contacts mobile layout by centering the avatar in a circular container and improving the layout of the name and description. - Move the agent avatar next to the record name in the AI Composer kanban view to optimize space usage. - Remove unnecessary empty space in the AI Skill form view so the form uses the available width on mobile. task-6366399 Forward-Port-Of: odoo/enterprise#123688
New planning shifts now use the user's timezone when setting default working hours. This keeps the default shift time at 8 AM to 4 PM locally, avoiding unintended time offsets for users in different countries.
Original PR description
Before: When creating a new shift, we set 8 AM - 4 PM as the default hours in UTC. With the timezone in Belgium, this becomes 10 AM - 6 PM. After: Change the timezone of the new shift to match the user's timezone. This will make the hours always be from 8 to 4 (working hours) --- task-6285596 Forward-Port-Of: odoo/enterprise#120062
Shop floor users can now see employee profile photos instead of generic placeholders when viewing or changing operators. This makes it easier for manufacturing teams to identify colleagues and reduces confusion during work order operations.
Original PR description
Currently when a shopfloor operator modifies the operator, operator images are not visible and only place holder images are visible. ## Steps to produce: - Install Manufacturing with demo data -…
Currently when a shopfloor operator modifies the operator, operator images are not visible and only place holder images are visible. ## Steps to produce: - Install Manufacturing with demo data - Login as Marc Demo - Open shopfloor ## Observed Behavior: Operator is unable to see their own profile picture and when you press the Edit Operator the operator is not able to see their as well as other operators images as well. ## Root cause: This issue occurs because by default an operator's user does not have access right for `Employees` in Human Resources section as they are not an HR officer nor an administrator. So when the user tries to access the image url that is meant for users with those access rights (HR officer / Administrator) at [1] and at [2]. The system returns a placeholder image instead of the employee image since the operator does not have access to hr employee model but does have access to hr employee public as per this [commit](https://github.com/odoo/odoo/commit/c9ca3761464413327d2beb697553a3ccd7eef4d1) [1]- https://github.com/odoo/enterprise/blob/5fe2fb44f4c8a938390343f7cdc90674cbf09391/mrp_workorder/static/src/mrp_display/dialog/mrp_employee_dialog.js#L16 [2]- https://github.com/odoo/enterprise/blob/5fe2fb44f4c8a938390343f7cdc90674cbf09391/mrp_workorder/static/src/mrp_display/employees_panel.xml#L9-L10 ## Solution: Allowing operators to see images can be done by modifying the links to use the public model instead of the private model. This will allow operators see other operators based on images and should improve user experience. | Before | |--------| | <img width="1865" height="844" alt="image" src="https://github.com/user-attachments/assets/c28f4209-0a60-486a-bfec-2a4db39cd946" /> | | <img width="995" height="899" alt="image" src="https://github.com/user-attachments/assets/7541edd9-6cc9-42d1-b5c5-39e0740d9a93" /> | | After | |--------| | <img width="1881" height="903" alt="image" src="https://github.com/user-attachments/assets/df3f8357-5cc2-4688-83dd-9a009fd56957" /> | | <img width="1221" height="862" alt="image" src="https://github.com/user-attachments/assets/c9d72b07-e1ad-43e4-85f5-00d8f1db9095" /> | opw-6321989 Forward-Port-Of: odoo/enterprise#123540 Forward-Port-Of: odoo/enterprise#121751
Belgian payroll warnings now apply the correct scope so users do not encounter access errors for items outside Belgium payroll. This helps payroll teams use the app more reliably without being blocked by unrelated warnings.
Original PR description
Some payroll warnings in BE were missing correct filtering to avoid access errors on things outside of the BE scope. Forward-Port-Of: odoo/enterprise#123769 Forward-Port-Of: odoo/enterprise#123554
Opening access rights for Sign templates no longer triggers an error when group permissions are displayed. The change prevents the system from requesting unsupported display data for user groups, making template access management work reliably.
Original PR description
Version: - saas-19.4 Steps To Reproduce: - Go to Configuration -> Settings. - Enable 'Manage Template Access' option. - Open any Sign template. - Click the gear icon and then click on 'Access Rights'. Issue: - Opening the template access rights dialog caused an RPC error. Cause: - The Many2Many tags configuration added the `color` field for all related models, including `res.groups`, which does not have 'color' field. Solution: - Skip adding the `color` field for the `group_ids` relation so only supported models request it. task-6348673 Forward-Port-Of: odoo/enterprise#122421
The website now shows the exact discount percentage configured for subscription products when prices are displayed with taxes included. This prevents customers from seeing a lower discount than intended, such as 4% instead of 5%, improving pricing clarity and trust during checkout.
Original PR description
Steps to reproduce: 1. Install eCommerce and Subscriptions. 2. Create a 21% Excluded tax. 3. Create a subscription product with a price of 45 with 21% tax and enable "Accept One-Time" in the…
Steps to reproduce: 1. Install eCommerce and Subscriptions. 2. Create a 21% Excluded tax. 3. Create a subscription product with a price of 45 with 21% tax and enable "Accept One-Time" in the Recurring Prices tab. 4. Publish the product on the website under the Sales tab. 5. Create a pricelist for 6 months recurring with two lines: - If min quantity is 0, then 0% discount - If min quantity is 2, then 5% discount 6. Set "Display Product Prices" to "Tax Included" in the Settings. 7. Open the product on the website, select the 6-month plan, and increase quantity to 2. Issue: The discount percentage displayed on the website shows 4% instead of the configured 5%. Why this happens: In `_get_additionnal_combination_info`, the discount is reverse-calculated from the tax-included price vs the tax-included sales price. When the 21% tax is included to both prices, it introduces a floating-point precision loss (4.9954..%), which floor() then truncates to 4%. Fix: When the pricelist rule uses 'percentage' discount, read `percent_price` directly from the pricing rule instead of reverse-calculating from tax-adjusted prices, as it represents the exact discount percentage the merchant configured with no floating-point involvement. opw-6224735 Forward-Port-Of: odoo/enterprise#121654
Point of Sale online orders from UrbanPiper and related platforms are now fetched together instead of through multiple separate requests. This reduces waiting time during order refreshes and lowers unnecessary server traffic, improving day-to-day POS responsiveness.
Original PR description
Issue: pos_urban_piper overrode getServerOrders() to add a separate loadServerOrders() call for it's own orders before delegating to super, resulting in up to an additional sequential RPCs on every order fetch. Fix: Extract the base query domain into a new overridable getServerOrdersDomain() method. Each module overrides it to OR in its own domain via Domain.or([super.getServerOrdersDomain(), extraDomain]), so all orders are fetched in a single RPC call instead of three. Task-6284860 Forward-Port-Of: odoo/enterprise#123679 Forward-Port-Of: odoo/enterprise#120001
Fixes an issue where using the mute button during VoIP demo calls could cause the call screen to crash. Demo calls now handle microphone muting more realistically, improving reliability for users evaluating or testing the calling experience.
Original PR description
Since commit [1], clicking the "mute" button during demo calls crashed. This is because the mocked SIP.js object now includes a `peerConnection` which was the guard against actually toggling microphone input. Now we do mock microphone toggling as well, preventing the crash, and making demo calls more realistic at the same time too. [1]: https://github.com/odoo/enterprise/commit/351dac8a19b581bc0892f18c3048228471c28238 Related to task-6361911 Forward-Port-Of: odoo/enterprise#123072
The Argentine VAT Book ZIP export no longer fails for partners marked as foreign providers with a foreign ID. This helps accounting users complete VAT reporting for cross-border transactions without manual workarounds.
Original PR description
Steps to reproduce: - Create a partner with: - State: Ireland - Identification Number: Foreign ID 55000004153 - ARCA Responsibility Type: Proveedor del Exterior - Create an invoice for the partner - Accounting > Reporting > Tax report - Select Report: VAT Book (AR), Tax Type: Sales - Click on gear icon > VAT Book (ZIP) Issue: Action will be blocked with error "No VAT configured for partner [58] <partner>" Analysis: Partners with ARCA responsibility type 'Proveedor del Exterior' (code 8) and a ForeignID identification type, causes a UserError when exporting the VAT Book (ZIP). Code 8 (foreign provider) is the purchase-side counterpart of code 9 (foreign customer), which already fell back to the country-level VAT. Extend the existing fallback branch to cover both codes. opw-6316008 Forward-Port-Of: odoo/enterprise#123506
Kenyan POS refund validation now works reliably without showing an error after a refunded sale. The fix also improves handling when multiple offline POS orders sync together, ensuring orders are sent to eTIMS correctly without disrupting cashier workflows.
Original PR description
Steps to reproduce: 1. Install `l10n_ke_edi_oscu_pos`, set company to Kenya. 2. Sell and validate an order. 3. Refund it from the POS and validate the refund order. Issue: - A traceback is raised…
Steps to reproduce: 1. Install `l10n_ke_edi_oscu_pos`, set company to Kenya. 2. Sell and validate an order. 3. Refund it from the POS and validate the refund order. Issue: - A traceback is raised when validating the refund: `ValueError: Expected singleton: pos.order(<refund>, <original>)` raised in `get_l10n_ke_edi_oscu_pos_data`. Cause: - When syncing a refund, `sync_from_ui` returns both the new refund order and the original refunded order. `waitForPushOrder` forces post-processing for every Kenyan order in that list, so `beforePostPushOrderResolve` receives both ids in `order_server_ids` and forwards them as-is to `action_post_order` and `get_l10n_ke_edi_oscu_pos_data`, both of which expect a single record. `action_post_order` fails the same way, but its error was silently swallowed by the surrounding try/catch, letting the traceback surface only on the second call. - The same multi-id list is also produced whenever several orders created offline get synced together once back online. Solution: - `get_l10n_ke_edi_oscu_pos_data` is only needed for the receipt of the order being validated, so call it with `order.id` instead of the full `order_server_ids` list. - Replace the `action_post_order` call with `action_post_selected_orders`, which posts each order individually and skips ones already sent to eTIMS, correctly handling both the refund case (original order is already `sent`) and the offline multi-order sync case. opw-6364221 Forward-Port-Of: odoo/enterprise#123043
This update fixes several small issues in accounting reports, including an unnecessary currency warning, a crash when dismissing warnings too quickly, and confusing audit behavior for budget-related values. It also hides an irrelevant setup field for composite reports and improves the appearance of working file cards, making reports clearer and more reliable for users.
Original PR description
**Commit 1: [FIX] account_reports: warning for CTA visibility** Steps to reproduce: - Open the balance sheet -> The warning for CTA is displayed even when a single company is selected. It should only…
**Commit 1: [FIX] account_reports: warning for CTA visibility**
Steps to reproduce:
- Open the balance sheet
-> The warning for CTA is displayed even when a single company is selected.
It should only be the case if multiple companies having different currencies
are involved in the computation of the report.
**Commit 2: [FIX] account_reports: hide groupby field on form view for composite report**
this field is useless for composite reports.
**Commit 3: [FIX] account_reports: differentiate UX for auditable external values.**
When creating a budget in the P&L, the external value cells should not be
auditable. The data was properly set but not the templates.
**Commit 4: [FIX] account_reports: avoid traceback on double-click on warning**
Steps to reproduce:
- Open an accounting report with any warning banner ("draft entries" for example)
- Quickly double-click the delete cross button
-> traceback stating that it cannot read properties of null (reading 'remove').
**Commit 5: [FIX] account_reports: working file card style adjustments**
<img width="401" height="317" alt="image" src="https://github.com/user-attachments/assets/76f636f0-09d8-44e5-8c7c-37561dc00b10" />
task-6361495
Forward-Port-Of: odoo/enterprise#123004Donation products created by the website subscription app will no longer automatically include the company's default sales tax. This prevents donors from being charged tax on donations, aligning the checkout amount with the intended donation value.
Original PR description
**Steps to reproduce:** 1. Install `website_sale_subscription` 2. Open the Products page, search for Donation and open the products **Issue:** A default Sales Tax is applied on the donation products. If a visitor donates money, they will be charged the sales tax. **Expected behavior:** Donation products should not include tax when web visitors donate money. Tax responsibility does not fall on the donors. **Why this happens:** When a `product.template`record is created without an explicit `taxes_id`, the field falls back to the default, which resolves to `company.account_sale_tax_id`. opw-6367188 Forward-Port-Of: odoo/enterprise#123771
This fix prevents an automated tax return validation test from failing when PDF generation overlaps with browser activity. It improves the reliability of quality checks without changing the tax return experience for users.
Original PR description
Validating a return renders the report to a PDF via wkhtmltopdf inside the `action_validate` request. During the render, the HttpCase test cursor is reserved for wkhtmltopdf, so any browser RPC that overlaps the render window is rejected, resulting in ConnectionLostError. Patching the `_run_wkhtmltopdf` so no real rendering runs during the tour. runbot-243444 Forward-Port-Of: odoo/enterprise#123809 Forward-Port-Of: odoo/enterprise#123720
This fixes an automated Knowledge app test that broke after a menu was changed from a dropdown button to a select menu. It also makes the test more reliable by addressing timing issues, helping prevent false failures in quality checks.
Original PR description
The dropdown for property definition type was replaced with a select menu, leading to an error in the tour as it tried to search for the previous implementation which contained a button. There are also changes to fix the race conditions that exist in the tour which were not evident due to the original issue Related pr: https://github.com/odoo/odoo/pull/234484 runbot-238409 Forward-Port-Of: odoo/enterprise#121958
Appointment blocks using picture or list layouts now show prices according to the website's tax display setting. This prevents customers from seeing tax-excluded prices when the site is configured to display tax-included pricing.
Original PR description
When the `appointments_template_picture` and `appointments_template_list` templates were added to `website_appointment_account_payment` in 19.0+, the corresponding overrides in `website_appointment_sale` were not added. This caused the picture and list appointment blocks to display prices using `product_lst_price` (always tax-excluded), ignoring the website's tax display setting (`show_line_subtotals_tax_selection`). The cards template already had a proper override using `_get_combination_info()`, which correctly handles everything. Steps to reproduce: 1. Go to Website > Configuration > Settings > enable "Tax Included" 2. Create an appointment type with a product that has taxes 3. Edit website page > add "Appointments" snippet > select "Picture" or "List" layout => price shown is tax-excluded Ticket [link](https://www.odoo.com/odoo/project.task/5799252) opw-5799252 Forward-Port-Of: odoo/enterprise#123448 Forward-Port-Of: odoo/enterprise#106643
This fixes a display issue in Planning where material resource rows could have the wrong height after the resource field changed to support multiple values. The list view now applies the intended styling to avatar fields, making schedules easier to read and visually consistent.
Original PR description
commit - https://github.com/odoo/enterprise/pull/106700/changes/3f27d96bda7c0b20683adb3fc1d38b5c3279c4a4 When the resource field was converted from m2o to m2m, the corresponding SCSS selector in the planning list was not updated. so the row height was not adjusted correctly for material resources using the m2m avatar widget. Forward-Port-Of: odoo/enterprise#123894
Philippine 2306/2307 reports now correctly include withholding taxes that are recorded when a vendor bill is paid, rather than only when the bill is created. This prevents missing or incorrectly signed income payment amounts, helping businesses produce accurate tax reports.
Original PR description
Withholding taxes flagged as withhold-at-payment book their tax line on the payment's move instead of the vendor bill. This broke the 2306/2307 report two ways: the income payment base came out with the wrong sign, since bill and payment entries store it oppositely, and the per-move scoping only looked at the bill's own move, so bills paid this way had nothing to show. Normalize the base sign using the tax line's sign instead of the base's own, and extend the scoping to also match lines booked on a payment registered against the bill. task-6319767 Forward-Port-Of: odoo/enterprise#121573
The Tasks Gantt view now correctly shades unavailable time when a user has employees in multiple selected companies. This keeps the visual schedule aligned with time-off warnings, helping planners avoid assigning work during approved absences.
Original PR description
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and…
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and create a task during the approved time-off period the warning is shown and the Gantt cell is grayed out. - Select both companies and create a task during the same time-off period in Tasks > Gantt. Issue: When multiple companies are selected, the time-off warning is still displayed but the corresponding Gantt cells are no longer grayed out, leading to an inconsistency between the warning logic and the Gantt rendering. Cause: In multi-company setups, a user can be linked to multiple resources. The Gantt unavailability logic assumed a one-to-one relationship between user and resource causing unavailability intervals from some resources to be overwritten. Solution: Aggregate unavailability intervals from all resources linked to the same user, limited to the selected companies, and merge them with the company calendar unavailability to ensure consistent Gantt gray rendering. Related PR: https://github.com/odoo/enterprise/pull/57028 task-5089385 Forward-Port-Of: odoo/enterprise#123732 Forward-Port-Of: odoo/enterprise#105288
Removing an icon from a Knowledge article header now works without triggering an error. This prevents an unexpected interruption for users editing articles and keeps the icon picker flow reliable.
Original PR description
Steps to reproduce: ------------------------------------ 1. Install the Knowledge module. 2. Open any article. 3. Click the header icon. If no icon is present, add one from the Actions menu. 4. Click…
Steps to reproduce: ------------------------------------ 1. Install the Knowledge module. 2. Open any article. 3. Click the header icon. If no icon is present, add one from the Actions menu. 4. Click the header icon again. 5. Click Remove icon from the emoji picker. Observation: ------------------------------------ A traceback is raised when removing the header icon. ``` TypeError: Cannot set properties of undefined (setting 'scrollTop') ``` Issue: ------------------------------------ The emoji picker component updates its scroll position through a grid reference. After this PR - https://github.com/odoo/odoo/pull/269588, the emoji picker was migrated to Owl 3, which changed the way component references are handled. The header icon removal flow still uses the previous ref access pattern, causing the grid reference to be `undefined` when attempting to update `scrollTop`, resulting in a traceback. Solution: ------------------------------------ Update the syntax for accessing the ref signal. Forward-Port-Of: odoo/enterprise#123880
The timesheet billable checkbox is now hidden when a project or task has no linked sales order, so users no longer see an option that cannot affect billing. This reduces confusion when entering time and makes the timesheet interface better reflect the actual billing setup.
Original PR description
Previously, the `is_billable` checkbox was visible in the timesheet systray even when no Sales Order was linked to the project or task. Toggling the checkbox in this state had no actual effect on billing, leading to user confusion. This commit introduces a non-stored computed field `has_available_so` on `account.analytic.line`. This field evaluates whether billing is possible based on the project and task configuration, and is used to conditionally hide the checkbox in the UI. task: 6328661 Forward-Port-Of: odoo/enterprise#122326
Features or functions removed from Odoo
An obsolete date calculation tied to scheduling follow-up activities from the VoIP call log was removed. This keeps the VoIP codebase cleaner after that scheduling option was removed, with no expected change for day-to-day users.
Original PR description
In [1], we remove the option to schduele a new activity on the log call wizard, so we don't care about `date_deadline` anymore. `_compute_date_deadline` then becomes useless and can be removed. [1]: d037568f8cba0de0aa313fafb4eb24d312d3e707 Forward-Port-Of: odoo/enterprise#123864
Code cleanup and technical improvements
The Knowledge comments area was internally updated to stay compatible with the newer interface framework. This should preserve the existing comments experience while reducing future maintenance risk.
Original PR description
`useLayoutEffect` is deprecated in OWL3. This replaces it with `useEffect` and moves the vertical-positioning logic into a `threadTops` getter. Two `useLayoutEffect` calls existed: one ran a batched…
`useLayoutEffect` is deprecated in OWL3. This replaces it with `useEffect` and moves the vertical-positioning logic into a `threadTops` getter. Two `useLayoutEffect` calls existed: one ran a batched vertical-dimension computation on `activeThreadId` change, the other a debounced horizontal computation on `editorThreads` change. - Horizontal: kept as a `useEffect`. Where the old hook ran on every patch, the OWL3 effect only reacts to the values it reads, so it reruns just when threads are added or removed. - Vertical: the positions can simply be derived while rendering, so the logic moved into a `threadTops` getter used by the template. This lets the render react to the relevant state on its own and drops the post-patch hook. The refactored code has test coverage — these failed when the effect was commented out and now pass: - TestESLint.test_eslint (`activeThreadId` defined but never used) - TestKnowledgeArticleTours.test_knowledge_article_comments (comments UI broken) runbot build with the effect commented out: https://runbot.odoo.com/runbot/batch/2594694/build/114736755