Daily updates from Odoo
Friday, August 7, 2026
23 changes · master
New functionality added to Odoo
Philippine payroll now supports preparing the monthly Social Security System contribution declaration required from employers. Businesses can generate the required semicolon-delimited employee contribution file more easily, reducing manual compliance work.
Original PR description
Philippine employers must submit a monthly contribution collection list to the Social Security System, as a semicolon delimited text file listing every employee, their compensation and their status. This adds a monthly SSS Contribution declaration from which that file can be generated. task-6321522
Enhancements to existing features
Belgian payroll eco voucher calculations now use working days to determine employee entitlements. This improves payroll accuracy and helps align voucher amounts with actual work patterns and related compliance checks.
CRM lead cards no longer show the phone plus/minus control for quickly adding or removing call activities, reducing visual clutter for upcoming designs. Users now add call activities through a selection-based action in kanban or list views, also available for contacts, with clearer handling when records already have a call or lack a phone number.
Original PR description
*: test_mail_enterprise Before this commit, on CRM leads kanban cards, there was a phone and plus/minus icon button that allowed users to easily add/remove call activities due or overdue for today…
*: test_mail_enterprise Before this commit, on CRM leads kanban cards, there was a phone and plus/minus icon button that allowed users to easily add/remove call activities due or overdue for today for that lead. While this was nice, it encumbered the card and will not fit nicely in new designs anymore. Instead, this is replaced by an action button that appears when you select records, in kanban or lists. This is also added for simple contact records (all models using the `voip.queue.mixin` at the moment). Side-effects: - You don't have to possibility to delete calls from the queue easily anymore (you have to do it one-by-one). Functionally it might be better to have the opportunity to cancel and log the reason anyway. - If you try to add a call activity while there is already one, it does nothing for the related call. - If you try to add a call activity but there is no phone number, it will prevent you to add the activity on all selected calls (with a message explaining what record prevented the action). task-6377768
Users can now resend invitations to document members who were previously invited but have not signed up yet. This makes it easier to follow up with pending collaborators directly from the document sharing dialog, without affecting active members.
Original PR description
This commit allow users to re-invite document members who were previously invited but haven't logged in yet, from the document share dialog. The 're-send' option is only displayed for members who have not signed up yet. Task-6040696
This update prevents duplicate default prompt setups for the same AI agent context, reducing inconsistent behavior and runtime errors. Existing duplicates are cleaned up during upgrade so the new rule can be applied safely.
Original PR description
## Summary This PR adds a unique index on `ai.composer` to prevent duplicate **Default Prompts** for the same **AI Agent**, **interface key**, and **focused model**. Previously, multiple records…
## Summary This PR adds a unique index on `ai.composer` to prevent duplicate **Default Prompts** for the same **AI Agent**, **interface key**, and **focused model**. Previously, multiple records could exist for the same `(ai_agent_id, interface_key, focused_model_id)` combination, leading to inconsistent data and runtime issues such as singleton errors when the AI composer expected a single matching record. The unique index uses PostgreSQL's `NULLS NOT DISTINCT`, ensuring that `NULL` values in `focused_model_id` are treated as equal and duplicate generic Default Prompts are also prevented. ## Changes - Add a unique index on the `(ai_agent_id, interface_key, focused_model_id)` triplet. - Use `NULLS NOT DISTINCT` to enforce uniqueness even when `focused_model_id` is `NULL`. - Add test cases to verify the unique constraint behavior. ## Upgrade Duplicate `ai.composer` records are removed before applying the unique index. Upgrade PR: https://github.com/odoo/upgrade/pull/10819 --- opw-6323764 Forward-Port-Of: odoo/enterprise#121609
Payment files now include the building number in ISO20022 address data, aligning SEPA credit transfer and direct debit exports with requirements that become mandatory in November 2026. This helps businesses remain compliant with upcoming banking standards and reduces the risk of payment file rejections later.
Original PR description
This commit adds the <BldgNb> node in the iso20022 XML files, as it will be mandatory starting November 2026. Linked: https://github.com/odoo/odoo/pull/271855 task-6317758 Forward-Port-Of: odoo/enterprise#126734 Forward-Port-Of: odoo/enterprise#121674
Payroll accounting entries are now grouped more efficiently when many payslips are processed together. This reduces validation time for large payroll runs, helping accounting teams complete batch processing much faster without changing the resulting entries.
Original PR description
Description =========== When batch payroll journal items are enabled, all payslips for the same journal and accounting period contribute to one accounting move. For every salary line,…
Description
===========
When batch payroll journal items are enabled, all payslips for the same journal and accounting period contribute to one accounting move.
For every salary line, `_prepare_slip_lines()` searched the complete list of previously prepared move lines for both the debit and credit entries. It also created a new `line_ids + new_lines` list for every search. As the move grew, accounting validation time grew quadratically.
This commit keeps a shared index while preparing the move. It is keyed by the stable aggregation fields: line name, account, and analytic distribution.
Only lines in the matching bucket must then be checked for compatible debit or credit signs and tax tags.
Benchmark
=========
The blueprint creates 500 validated payslips and 10,000 payslip lines. All lines are accumulated into one accounting move.
On a fresh database with `hr_payroll_account` and `populate` installed, populate the data with:
```sh
./odoo-bin populate\
-d <database> \
-b hr_payroll_account.benchmark_payroll_account_move_creation \
--seed 42
-j 4
```
Run the benchmark with from the [gist](https://gist.github.com/pivi-odoo/3a5a21bb42f82d5ae10646d15986013b):
```sh
./odoo-bin shell \
-d <database> \
< benchmark_prepare_slip_lines.py
```
The benchmark measures `_get_account_move_vals()` with a cleared ORM cache before every sample.
| Payslips | Input lines | Move lines | Before | After | Speedup |
|---------:|------------:|-----------:|--------:|-------:|--------:|
| 20 | 415 | 398 | 0.634s | 0.093s | 6.8x |
| 50 | 1004 | 986 | 3.040s | 0.178s | 17.1x |
| 100 | 1992 | 1974 | 11.865s | 0.344s | 34.5x |
| 200 | 3942 | 3884 | - | 0.648s | - |
Reference
=========
task-6429789Belgian payroll reporting now excludes employees marked as not subject to withholding taxes from key fiscal reports. This helps ensure employees who are not taxed in Belgium are not incorrectly included in 281 and 274 tax reporting.
Original PR description
Purpose: Some employees should not have any withholding tax and some should not have any fiscal report neither as they are not taxed in belgium. - excluded employees with `no_withholding_taxes` checked from 281 and 274 reports. task-id: 6377289
The Time Off Gantt view popover now lets users edit leave records directly and split a leave into two parts. This makes scheduling adjustments faster and reduces the need to navigate away from the planning view.
Original PR description
- Make the leave record in the popover editable. - be able to split a leave in 2 task-6345738
The Belgian payroll exemption wizard and reports now consistently show the Start-up and Micro-enterprise sections only when the company is eligible. This helps prevent employers from generating irrelevant or invalid 274.60/274.61 report sections when their SME exemption status is missing or expired.
Original PR description
Make the form view, PDF, and XLSX reports consistent when reporting the Start-up (274.60) and Micro-enterprise (274.61) exemptions. Specifically: - Hide the "Start-up/M-E" tab in the wizard form view if the company's exemption SME status setting is not configured. - Do not generate the 274.60/61 tab/worksheet in the XLSX file if the employer is ineligible (i.e. status is empty or CBE has expired). - Do not generate the 274.60/61 page in the PDF printout if the employer is ineligible. task-6421989
Live chat and Discuss now have a cleaner interface with fewer distracting icons. Users can translate new messages more easily within a conversation, canned responses are ordered by recent usage, and conversations can be downloaded before a chat ends.
Original PR description
This commit aims to improve the UI of livechat and discuss by removing clouding icons. It improves the UX by having the option to translate all new messages when translating one message, this is a client side option meaning it would need to be done again after refresh and is isolated to the current channel. We also improve the sort of canned responses by using the last used canned function Odoo-wide (depends on other users as well) and being able to download conversations even when the livechat is not ended. https://github.com/odoo/odoo/pull/270509 Task-6272656
Certificates of Completion for Sign requests now show timestamps in the sender's timezone instead of always using UTC. This makes the certificate easier to understand for signers and reduces confusion for teams working across regions.
Original PR description
The Certificate of Completion always displayed timestamps in UTC, which confused signers in non-UTC regions. They are now shown in the request sender's timezone. task-6046266
Belgian payroll now warns users when company car details are updated after the DMFA declaration has been prepared. It also records the update date, helping payroll teams identify changes that may affect reporting accuracy and compliance.
Original PR description
Task: 6201452
Improves the Brazilian fiscal localization screens and labels so business users can configure tax and fiscal data with clearer wording and fewer duplicate options. It also improves product and contact fiscal code handling, archiving of NBS codes, and gives clearer validation messages for correction letters before they reach external tax services.
Original PR description
This contains a bunch of UX and data cleanups across the Brazilian fiscal localization: - Selection labels for activity sector, tax regime and SPED type now have human-readable text instead of the…
This contains a bunch of UX and data cleanups across the Brazilian fiscal localization: - Selection labels for activity sector, tax regime and SPED type now have human-readable text instead of the raw API codes, SPED type is prefixed with its official code, - NCM codes get a new is_service flag distinguishing goods (NCM) from services (LC116), with search filters, a "NCM / LC Codes" menu and a product code field filtered on the product type, - NBS codes can now be archived, - Clean up the settings: rename "Simplified Regime ICMS Rate" to "ICMS Simplified Credit Rate" with a Brazil-specific tooltip, drop the duplicate CBS/IBS Normal toggle (kept on the company contact) and align the CNAE field, - Show the operation type Technical Name on its form, - Reorder the contact Fiscal Information fields and rename the product "Transport Cost Type" to "Additional Cost Type", - Open the partner form when a single contact is missing Avatax fields, and the Brazil-specific list for several, - Validate the correction letter reason length in Odoo so a short reason no longer shows a raw XML schema error from Avalara, task-6327269
Resolved issues and error corrections
Several parts of the system now properly clean up background event listeners when screens or interactions close. This prevents gradual slowdowns and avoids repeated duplicate actions during long user sessions.
Original PR description
*: knowledge,social_push_notifications,web_studio Bus listeners were not removed on component/interaction destruction, causing memory leaks and duplicate event handling over a session. Add useBus() for Owl components and addBusListener() for public interactions to automatically manage listener cleanup.
Fixes an issue where customer follow-up reminders could choose different overdue invoice lines in different parts of the system. This ensures the correct follow-up step and responsible person are applied consistently, avoiding missed or incorrectly assigned reminder activities.
Original PR description
[FIX] account_followup: fix oldest follow-up move line mismatch
`compute_followup_line` and the `_get_followup_data_query` SQL query were inconsistent when determining the oldest move line.
runbot-944619The salary calculator now keeps the selected net monthly budget view instead of briefly showing it and reverting to yearly values. This prevents confusion when HR users test salary scenarios and helps ensure temporary calculator changes are safely rolled back as intended.
Original PR description
### Description of the error in the salary calculator, when selecting 'net per month', the form glitches: it shows for a brief moment the desired behavior, until the budget type returns to yearly with yearly values. ### Explanation In the context helper of version, we can create a savepoint. This savepoint is important in the context of the calculator: if we select an employee, then play around with their numbers, it is important that the modification made are rolled back and that we reach a savepoint. However, we make sure that we don't run recursively the context helper. This is an issue: if the calling context, which is called with `invalidate = False`, calls once again the context (in the case of a compute triggering another compute for example) with `invalidate = True`, we will just get out of the context before validating it. __ task-6357973
This fixes an issue in UK reports where selecting a tax unit while filing a VAT return could fail because the report options were read incorrectly after an internal framework change. Users can now confirm the tax unit selection without the process breaking.
Original PR description
Enterprise counterpart of odoo/odoo#281228 — same scope, same criterion. The Owl 3 migration changed contracts (refs became `signal.ref()`, `AccountReportController.options` became a signal) and left…
Enterprise counterpart of odoo/odoo#281228 — same scope, same criterion. The Owl 3 migration changed contracts (refs became `signal.ref()`, `AccountReportController.options` became a signal) and left some consumers reading the old shape. This PR collects **our own oversights**: call sites that were already on master when we changed the contract under them. Forward-ports that landed *after* a contract change are handled separately, in odoo/enterprise#127207, so the two can be reviewed and backported independently. ### Fixed - [x] `l10n_uk_reports` — `patch_button_report.js` read `this.options.available_tax_units` on what Reactivalypse had turned into a signal three weeks after this code landed. Confirming "Select Tax Unit" when filing a VAT return from a company that belongs to a tax unit throws on `[0]`, and `saveSessionOptions` was handed the signal itself rather than the options. ### Coverage Enterprise has not had the systematic sweep that odoo/odoo#281228 got. `rootRef.el` is clean, and the ref-contract check over forward-ports came back clean apart from #127207, but the equivalent of that PR's `signal.ref()`-declaration audit has not been run here, and reads of properties a refactoring turned into signals — the `options` shape above — have no syntactic tell and are not greppable at all. Expect more sites to land in this PR.
Customer balances in Point of Sale now show the correct amount when the company and PoS use different currencies. This prevents customers’ “Total Due” from being understated or overstated because pay-later payments were converted twice.
Original PR description
Steps to reproduce: - set the company currency to XCG - set the PoS sales journal currency and the PoS pricelist currency to USD - configure a XCG <-> USD rate - create a customer without any…
Steps to reproduce: - set the company currency to XCG - set the PoS sales journal currency and the PoS pricelist currency to USD - configure a XCG <-> USD rate - create a customer without any outstanding balance - open the PoS, create an order of USD 100 and validate it with the Customer Account (Pay Later) payment method - open the Customers screen and look at the Total Due of that customer Issue: The Total Due shows about USD 55.56, i.e. the amount converted once too many, instead of the expected USD 100. Cause: get_total_due() sums two amounts that are not expressed in the same currency before converting them. partner.total_due comes from the accounting entries, it is the sum of account.move.line.amount_residual and is therefore in company currency, while total_settled is the sum of pos.payment.amount of the still open sessions, which is in the currency of the order, so the PoS one. The addition is done first and the result is then converted from the company currency to the PoS one, so the pay later payments end up converted a second time. opw-6403320 Forward-Port-Of: odoo/enterprise#126849 Forward-Port-Of: odoo/enterprise#125798
This fixes an issue where Tyro card payments with a surcharge could sometimes validate the point-of-sale order before the surcharge was added. Businesses using Tyro can now rely on the final order total including the surcharge consistently.
Original PR description
Currently when completing a Tyro payment with a surcharge fee in some cases there is a race condition preventing the surcharge line to be added to the pos order before its validation This PR fixes that issue opw-6402191 Forward-Port-Of: odoo/enterprise#126035 Forward-Port-Of: odoo/enterprise#125852
Commission achievement reports now include adjustments dated in the future when they fall within the relevant plan period. This gives businesses a more complete and accurate view of expected commission performance instead of hiding valid planned adjustments.
Original PR description
Before: - Adjustments dated after today were hidden in the Achievement report, even when the date was within the plan period. After: - Removed the today fallback from date filters in the achievement report. - All adjustments within the plan period are now visible. Task: 6292361
The VoIP keypad behavior has been clarified so only the main dialer or transfer flow can start calls or transfers. This prevents an in-call keypad action, such as pressing Enter after typing tones, from accidentally starting a new call.
Original PR description
The keypad had 3 calling usecases: - Hitting "Enter" in the number/contact input - Clicking a call/phone button - Longpress on the voicemail button This commit moves the responsibility of those…
The keypad had 3 calling usecases: - Hitting "Enter" in the number/contact input - Clicking a call/phone button - Longpress on the voicemail button This commit moves the responsibility of those actions to the parent component. Indeed, the keypad is used in 3 places: - Dialer: the main one. In the end the only wants who wants to initiate actual calls. It now passes "how to call" to the keypad, which does it for "Enter" / click a call button. It also passes "how to voicemail" which becomes the condition to display the voicemail button in the first place (instead of the keypad hardcoding "am I in the dialer?"). - Transfer during a call: same as the dialer, it passes "how to transfer" which the keypad does at the same places as "how to call". - DTMF keypad during a call: that one definitely don't need to know how call / transfer / voicemail so it is not given anything about that. Funny enough: the third case was actually buggy. If during a call you opened the DTMF keypad, hit numbers then hit "Enter"... you would start a new call with the DTMF numbers. This is fixed here but that part will get a dedicated minimal fix in stable, with a test, forwarding up to master later on. Related to task-6365445 Related to task-6455637
Code cleanup and technical improvements
The Knowledge app now uses a newer, supported way to manage comment screen updates, helping keep the feature compatible with upcoming platform changes. This also removes an obsolete scroll behavior and helps prevent comments from disappearing when switching or reloading articles.
Original PR description
Replaced `useLayoutEffect` with `useEffect` (from `@odoo/owl`) because `useLayoutEffect` is deprecated in OWL3. All 7 effects read their reactive deps naturally inside the body, so `useEffect` auto-tracks them without an explicit dep array. Two effects (`loadRecords`, `loadThreads`) subscribed to deps they did not read naturally via `void` expressions. The use layoutEffect refactored in this PR had test coverage — below are some tests that failed when the effect was commented out, and are now passing: - TestKnowledgeArticleTours.test_knowledge_article_comments see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2594700/build/114736861 `targetRef` was converted from a compat `useRef` to a native `signal.ref()`: `useEffect` runs before the DOM patch, so a compat ref's `.el` accessor is untracked and the popover effect never re-ran after mount; a signal ref triggers re-runs once the element is set.