Daily updates from Odoo
Monday, July 20, 2026
33 changes · master
New functionality added to Odoo
Businesses in the Philippines can now send BIR 2306/2307 withholding tax certificates directly to vendors from vendor bills. The feature supports both individual and batch emailing, helping teams save time and streamline tax compliance communication.
Original PR description
Add a mechanism to email the BIR 2306/2307 withholding tax certificate to the vendor from a bill, both individually and in batch. task-6298456
Adds an Argentina-specific Daily Book XLSX export so businesses can summarize journal entries by ledger instead of reporting every invoice individually. This helps reduce reporting volume and related page-based costs, while allowing users to configure the starting entry number and select relevant ledgers.
Original PR description
Purpose: Implement the daily book export for Argentina which allows users to summarize and report journal entries of the same nature, such as all sales, to reduce reporting every single invoice which…
Purpose: Implement the daily book export for Argentina which allows users to summarize and report journal entries of the same nature, such as all sales, to reduce reporting every single invoice which incurs a cost per page. Users can use the multi-ledger system to summarize the journal entries. Ledgers can be created and set on the journal. Journals of the same nature can share the same ledger. Then, the user can view and select which ledgers they want to export on the general ledger and then export. By default, all ledgers will be selected, until the user deselects ledgers. A "Daily Book XLSX (AR)" button was added and can be accessed in the dropdown of the cog menu. Upon click, a wizard will pop up and it will display the starting entry number for the report. By default, it will display 1 if there's no history or the last entry number (that we store) + 1. The user can input their own number. Once the starting number is set, the XLSX file for the daily book will export. task-5244083
Enhancements to existing features
Online payment initiation now includes the payer's bank account information and account holder name when sending payment requests. This helps meet requirements from providers like Powens and banks that need these details to process payments reliably.
Original PR description
With Powens, some banks requires the payer's bank information such as bank account number and bank holder name. This commit adds those informations to the odoofin route to be sent to the payment providers. task-6373634 Forward-Port-Of: odoo/enterprise#124930 Forward-Port-Of: odoo/enterprise#124088
This update aligns the naming used for a Mexican electronic invoicing method in the website sales flow. It helps keep the checkout and invoicing experience consistent with related Odoo changes, with minimal visible impact for users.
Original PR description
see community for reference: https://github.com/odoo/odoo/pull/276851
Obox can now send service failure messages to the Odoo database, where they are stored as logs. This helps users in debug mode and support teams see when an Obox service has failed, making diagnosis easier.
Original PR description
This PR adds a controller which allows the obox to contact the db to send a message. The db then creates an `obox.log` record which is visible in debug mode to the user. This is currently used to notify the databse when a service fails on the obox Obox PR: https://github.com/odoo/obox/pull/192
Updated accounting-related test cases to reflect the current way invoice and bill due dates are calculated. This helps keep automated quality checks reliable by expecting due dates to follow invoice dates and payment terms instead of defaulting to today.
Original PR description
Before this commit: Several tests still relied on the previous behavior where the Due Date was automatically set to Today's Date by default. Since the due date computation was updated, these assumptions caused the tests to fail. With this change: Updated the affected test cases to match the new due date computation. Tests now expect the Due Date to be computed based on the Invoice/Bill Date and selected Payment Terms. Where no Payment Terms are configured, tests now expect the Due Date to match the Invoice/Bill Date. task-6309674 Related - [odoo/community](https://github.com/odoo/odoo/pull/271831/)
Users can now delete attachments or add them to Documents directly while previewing a file. This saves time by avoiding the need to return to the chatter to perform common document actions.
Original PR description
Users can currently delete attachments or add them to Documents from the chatter. However, when opening an attachment in the file viewer, these actions are not available. This commit adds Delete and Add to Documents buttons in the file viewer, allowing users to perform the same actions without leaving the viewer. Related Community PR: https://github.com/odoo/odoo/pull/247924 <img width="972" height="362" alt="image" src="https://github.com/user-attachments/assets/51581ef5-5855-4cc4-b850-12b7a8e1af5e" /> Task-[5408185](https://www.odoo.com/odoo/project/1519/tasks/5408185)
WhatsApp conversation threads now display their associated avatar in the discussion view. This makes it easier for users to recognize and distinguish WhatsApp channels at a glance.
Original PR description
Purpose of this commit: Show thread avatar for channel type whatsapp Before <img width="462" height="134" alt="image" src="https://github.com/user-attachments/assets/72bc9bab-877d-4a42-aa3e-a7cfb12c6065" /> After <img width="624" height="107" alt="image" src="https://github.com/user-attachments/assets/ba6fe94a-7751-42e9-a1cc-4976c3d5eaa5" /> task-6398499
The French balance sheet report now places establishment costs before fixed assets and includes additional impairment accounts for tangible fixed assets. This improves the accuracy and presentation of French financial statements for reporting users.
Original PR description
Move establishment costs before fixed assets in the French balance sheet, and include the missing 2912, 2913, 2914, and 2915 impairment accounts in the relevant tangible fixed asset amortization/provision lines. task-6226138 Forward-Port-Of: odoo/enterprise#124562 Forward-Port-Of: odoo/enterprise#117689
Resolved issues and error corrections
This fixes balance receipt printing for SIX payment terminals after a prior change caused the receipt template to be loaded incorrectly. The receipt layout is now provided as its own template file, restoring the expected balance receipt behavior after the module is upgraded.
Original PR description
odoo/enterprise#104683 broke the balance receipt for six terminals trying to load an html template in a template name param. We fix this by extracting the template in its own file. Note: clients will have to upgrade the module in order to make the template available. task-6391500 Forward-Port-Of: odoo/enterprise#124521
Studio approval rules now handle restricted fields without causing an access error for users who do not have permission to see those fields. This prevents sales order confirmations and similar actions from being unexpectedly blocked while keeping the approval logic in place.
Original PR description
Issue: A studio.approval.rule.domain includes a related field that calls an access rights group that the user who used the action isn't apart of, Is blocked by the filtered_domain. To Replicate: 1) Install studio, sale, Accounting and make sure "account_followup" is installed 2) create a related field on the sales.order form related to "customer -> follow up status" 3) Save 4) Create a "Studio Approval Rule" (studio.approval.rule) with a domain using the new related studio field -> method : "action_confirm" -> approver:admin 5) create a test user with no accounting access rights 6) in an incognito browser try and create a sales order, and then confirm it. it will throw the access rights error Fix: add a sudo to the filtered_domain opw-6316069 Forward-Port-Of: odoo/enterprise#124722 Forward-Port-Of: odoo/enterprise#121856
The POS now loads only the Kenya e-invoicing code records that are actually used by products, instead of fetching entire code lists. This reduces unnecessary data loading and can improve POS startup performance for businesses using the Kenya OSCU localization.
Original PR description
Before `product.unspsc.code` and `l10n_ke_edi_oscu.code` records were loaded without domain, which could lead to loading all records of these models in POS, which is not necessary. This commit adds a domain to the loading of these records, so that only the records that are actually used in the products are loaded in POS. Forward-Port-Of: odoo/enterprise#124154 Forward-Port-Of: odoo/enterprise#123684
This fixes an error that could occur when opening a planning calendar popover in Field Service. The calendar now includes the needed user information so users can view planning details without hitting an unexpected crash.
Original PR description
add the user_ids field to the calendar view because its needed in a popover task: 6358644 Forward-Port-Of: odoo/enterprise#122684
VOIP call smart buttons now open the same full set of related records that they count, covering the customer’s company and related contacts. When creating a new record from a call, the system still defaults to the specific contact from the call, reducing confusion and keeping follow-up work accurate.
Original PR description
Commit [1] change the smart buttons on voip.call to count records from all family of the partner (count all record from all partners from the partner's company). However, the actions on the buttons stay the same, they will only open records from the partner itself. This is confusing, we change it to also show records from the whole partner family. [1]: 16772c5c1e604d6beb514f9e5b166fc0c2f452a7 Task-6379569 Forward-Port-Of: odoo/enterprise#123944
Polish currency rate imports now avoid applying an extra one-day date shift. This prevents rates from being dated too far back now that the system already uses the previous day's rate as required.
Original PR description
In Poland, it is mandatory to use the previous day's currency rate. We used to achieve this by shifting the rate's date by one day. Since https://github.com/odoo/odoo/pull/231948, we already use the previous day's rate, so the shift is no longer needed. See: https://www.odoo.com/mail/message/1118975071 Forward-Port-Of: odoo/enterprise#123849
Service sale order lines generated from planning now let Odoo calculate prices automatically instead of forcing a fixed unit price. This ensures customer or product pricelists are applied correctly, reducing incorrect billing for field service work.
Original PR description
Before this commit, in the method `_generate_service_sale_order_lines` the `price_unit` for sale order lines used an explicitly defined unit price. This prevented the pre-computation of the price. It may cause some issues, for example if there was a pricelist defined on the product, we didn't apply the prices from that pricelist. This commit removes explicit definition of the `price_unit` to let the sale order creation process handle it. [error-941068](https://runbot.odoo.com/odoo/error/941068) Forward-Port-Of: odoo/enterprise#124680
This fixes an error that could interrupt stock operations when using Kenya OSCU e-invoicing modules, especially in kit-related picking flows. The change helps ensure stock moves complete reliably without unexpected tracebacks.
Original PR description
**CAUSE** super()._action_done() delete a record from self, and return a new recordset of stock.moves. We filter the old recordset instead of filtering the new one, leading to an MissingError traceback. **STEP TO REPRODUCE** On a fresh db, install: `l10n_ke,l10n_ke_edi_oscu,l10n_ke_edi_oscu_mrp,l10n_ke_edi_oscu_pos,l10n_ke_edi_oscu_stock,l10n_ke_edi_tremol,l10n_ke_hr_payroll,l10n_ke_hr_payroll_account,l10n_ke_reports` and run `TestKitPicking.test_add_sml_with_kit_to_confirmed_picking`. runbot-241262 Forward-Port-Of: odoo/enterprise#124663
Mexican payroll CFDI generation now includes the employer CURP when the company represents an individual, identified by a 13-character RFC. This prevents validation errors for businesses under fiscal regime 621 and allows affected payslips to be generated correctly.
Original PR description
Issue: ---------------------------------------- There is a fiscal regime where the company is actually an individual but is authorized to generate documents. Steps to reproduce:…
Issue: ---------------------------------------- There is a fiscal regime where the company is actually an individual but is authorized to generate documents. Steps to reproduce: ---------------------------------------- - Install "l10n_mx_hr_payroll_account_edi" - Change the current company fiscal regime to '621' - Add an VAT of length 13 to the current company - Add a CURP number on the current company - In Payroll generate a payslip, validate it - Post the Journal entry - On the payslip, click "Generate CFDI" - An error is returned, saying the Emisor:Curp applies to individuals Cause: ---------------------------------------- An RFC of length 13 means that the sender is an individual. It's intended with the fiscal regime '621'. We add the curp number in the CFDI XML only when `self.company_id.partner_id.is_company` is `False`. Since saas-19.1, `is_company` is computed to be truely if a VAT is present. So as soon as the VAT is entered, the CURP number is absent from the XML. Solution: ---------------------------------------- We change the condition to add the CURP number in the XML: A VAT number of length 13 means the contact is an individual (12 for companies). This is what is used to validate the XML: if the vat is of length 13, then the curp number should be present. opw-6351558 Forward-Port-Of: odoo/enterprise#124868 Forward-Port-Of: odoo/enterprise#124027
The Sendcloud delivery test suite was corrected so it runs in regular CI instead of only nightly checks. This helps catch delivery integration issues earlier, including corrected expectations for multi-package weight handling.
Original PR description
Test class was tagged as external although calls are mocked. This means errors were only caught in nightly and not by CI. Removing the tag requires fixing some of the tests. For `test_multicollo`, we send the average weight of packages instead of the total since 97f82442c9fee7dcb3e8c5e9bacddcd6bb864e11. Forward-Port-Of: odoo/enterprise#121665 Forward-Port-Of: odoo/enterprise#111660
VoIP call screens now hide related record shortcuts when a call is not linked to a customer or contact, preventing errors from unexpected clicks. Subscription shortcuts are also shown consistently with the customer page behavior.
Original PR description
Same as in [1], we don't show smart buttons when no partner to prevent unexpected errors. Also remove `invisible="subscription_count == 0"` to make it same as smart button on res.partner. [1]: 0fbb730e02de22b196a45455f801e96321a75167 Forward-Port-Of: odoo/enterprise#124925 Forward-Port-Of: odoo/enterprise#124579
This update improves how email, SMS, and WhatsApp delivery failures and bounces are reflected in marketing automation campaigns. Businesses get more accurate campaign follow-up behavior and clearer failure information, while related tests were expanded to protect these workflows.
Original PR description
RATIONALE In order to prepare upcoming improvements for marketing automation application, as well as performance improvements, status update from sms / mail / whatsapp is checked, tested and fixed. Fixes are done in master mainly because it would be difficult in stable, and because those are not critical. SPECIFICATIONS See sub-commits for more details. Task-6401319: [mail_*] Fixup mail/sms/WA -> Trace -> MarketAuto update Task-4224152: [marketing_automation] Performance / Scalability
Fixed an issue where using the Off-Cycle filter in the payslips list could trigger an error in debug mode. The payroll screen now handles payslips without a pay run correctly, improving reliability for payroll users.
Original PR description
Before this commit, when the user is in debug mode, goes to payslips list view and applies `Off-Cycle` filter, a traceback is occured saying `Invalid props for component 'PayslipActionHelper': 'payrunId' is not a number`.
The reason is because we search the id of the payrun by parsing the domain applied to fetch payslips displayed inside the list view but `Off-Cycle` filter will apply the following domain: `[('payslip_run_id', '=', False)]` and so False is given to PayslipActionHelper but it is not a number.
This commit makes sure to set undefined to payrunId prop of PayslipActionHelper when `payrun_id` found is falsy.
runbot-error-241053
Forward-Port-Of: odoo/enterprise#124897
Forward-Port-Of: odoo/enterprise#124854AI-generated answers with web citations now preserve their original line breaks and spacing. This prevents lists and paragraphs from being accidentally merged, making cited responses easier to read and understand.
Original PR description
AI responses containing web citations lost their original formatting when a citation appeared at the end of a line, causing lists and paragraphs to be merged together. This commit limits the citation parser to ignore only horizontal whitespace around citations, preserving line breaks in the rendered response. task-6391187 Forward-Port-Of: odoo/enterprise#124457
The timesheet grid now uses updated colors for attendance/work rule types. This makes it easier for users to quickly recognize different event types at a glance.
Original PR description
This commit updates the color of AW rule types to help the user to quickly recognize the type of events based on the color. task-6186073 Forward-Port-Of: odoo/enterprise#124838
The Timesheets shortcut now appears whenever a user has an active employee profile in any selected company, not just the current company. This prevents eligible users from losing quick access to timesheet entry when working across multiple companies.
Original PR description
Steps to reproduce: - install Timesheets - create an employee for a user in company B - switch to company A (where the user has no employee) - the systray icon is hidden even though the user can…
Steps to reproduce: - install Timesheets - create an employee for a user in company B - switch to company A (where the user has no employee) - the systray icon is hidden even though the user can create timesheets in company B via the company selector Current behavior: the systray only checks the current company for a valid employee, ignoring other selected companies. Expected behavior: the systray should be visible whenever the user can create timesheets i.e. when they have an active employee in any of the selected companies. Issue: the check used a stored boolean on `res.partner` that has no company scope and becomes stale when an employee is archived (the stored dependency does not re-fire). the timesheet creation logic checks all selected companies for active employees, but the systray did not mirror that. Fix: use `employee_ids` a `One2many` that checks all selected companies and excludes archived employees, matching the timesheet creation logic exactly. task-6330539 Forward-Port-Of: odoo/enterprise#124830 Forward-Port-Of: odoo/enterprise#121730
Features or functions removed from Odoo
The India GST reporting flow now keeps only the newer HSN Summary format, which has been available for over a year. This simplifies maintenance and reduces duplicate reporting paths, while related test data for the retired format has also been removed.
Original PR description
As it has been more than a year since the new HSN Summary format was launched, this commit removes the old HSN Summary format for simplification. Additionally, it removes the related test cases as well. ref - https://github.com/odoo/enterprise/commit/8f3400d5037ea4aa23112ea7d65ae6afc7f488e4 https://github.com/odoo/enterprise/commit/d0df0f845ac2853d1247cae0d9543e92050bf2a4
Code cleanup and technical improvements
The Point of Sale code was updated as part of Odoo's OWL 3 migration, replacing older internal reference patterns with the newer approach. This is an internal modernization that helps keep PoS screens and related localizations maintainable without changing day-to-day user workflows.
Original PR description
pos*: pos_enterprise, l10n_at_pos, l10n_ke_edi_oscu_pos As part of the OWL 3 migration, this commit replaces `useRef` and `t-custom-ref` usages with `t-ref` and signal-based references across the PoS codebase. Task-6343663 Related Community PR: https://github.com/odoo/odoo/pull/272698
The grid view editing logic was updated to use newer platform APIs, replacing deprecated internals. This keeps spreadsheet-like grid inputs working reliably while reducing future maintenance risk as the web framework evolves.
Original PR description
Replaced two `useLayoutEffect` calls in `useInputHook` with OWL3 native APIs (`useListener`, `onMounted`, `onPatched`), since `useLayoutEffect` is deprecated in OWL3. The caller `GridCell` was…
Replaced two `useLayoutEffect` calls in `useInputHook` with OWL3 native APIs (`useListener`, `onMounted`, `onPatched`), since `useLayoutEffect` is deprecated in OWL3. The caller `GridCell` was updated to use `signal.ref()` instead of the compat `useRef`. The first effect attached `input`/`change`/`keydown` listeners to `inputRef.el` — a textbook `useListener` case. However, the compat `useRef` from `@web/owl2/utils` silently untracks the underlying signal on `.el` access, so `useListener(() => inputRef.el, ...)` never re-ran after mount and no listeners were attached. The fix passes the signal ref directly (`useListener(inputRef, ...)`) and upgrades the caller to use `signal.ref()` passed explicitly to the hook. The second effect (bare `useLayoutEffect` re-syncing the DOM value on every render) maps directly to `onMounted` + `onPatched`. The `useLayoutEffect` refactored in this PR had test coverage — below are some tests that failed when the effect was commented out, and are now passing: - `@web_grid/grid_view/grid_view_desktop/editing a value` - `@web_grid/grid_view/grid_view_desktop/Edition navigate with tab/shift+tab and enter key` - `@web_grid/grid_cells/float_time_grid_cell/FloatTimeGridCell in grid view` see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2624595/build/116553684
This change modernizes how scrolling behavior is connected in the Gantt and grid views. It should help keep these views aligned with the latest web framework patterns without changing the visible user experience.
Original PR description
The web `virtual_grid_hook` now attaches its scroll listener via `useListener` on a signal ref instead of `useLayoutEffect` on a compat `useRef`. This PR feeds it a signal ref from both enterprise callers:
- **web_gantt**: `scrollRef` becomes a `signal.ref` bound with `t-ref`; its own scroll `useLayoutEffect` becomes a `useListener` and all `.el` reads become calls. Layout's `contentRef` (now a signal, per the community PR) is adapted to an `{ el }` object ref for the draggable hooks (`useGanttDraggable`/`useGanttSchedulable`), which require an object ref.
- **web_grid**: `contentRef` prop type is now a function (signal) ref.This change keeps Enterprise list views in Web Studio and Data Cleaning compatible with an underlying platform update. It is an internal refactor with no expected change to day-to-day user workflows, helping prevent display or interaction issues after the core update.
Original PR description
That PR migrates the base `web.ListRenderer` `table` ref from the OWL2 compat `useRef`/`t-custom-ref='table'` to a native OWL3 `signal(null)` bound with `t-ref="this.tableRef"`. This PR updates the enterprise modules that still consume the old compat surface: - **web_studio** `ListEditorRenderer`: retargeted both xpath inheritors `//*[@t-custom-ref='table']` → `//*[@t-ref='this.tableRef']`, and `onTableHover` reads `this.tableRef()` instead of `this.tableRef.el`. - **data_cleaning** `DataMergeListRenderer.onGroupRowMouseEnter`: reads `this.tableRef()` instead of `this.tableRef.el`. Companion PR to odoo/odoo#272009.
Spreadsheet autofill for list and pivot data has been reorganized to align with the underlying spreadsheet engine. This is an internal cleanup that should preserve existing behavior while making the feature easier to maintain and slightly more efficient.
Original PR description
### [MOV] spreadsheet_edition: move list/pivot autofill plugins to helpers The list/pivot plugins were transformed into helpers in the last commit, this commit renames the files. ### [REF] spreadsheet_edition: make autofill plugin into a store The o-spreadsheet commit transformed the autofill plugin into a store. This made the necessary adaptations in odoo. Moslty, the list/pivot autofill plugin were changed into helpers that can be called from the autofill process (they had no state nor command handling). Also changed a bit the autofill helpers so we don't re-compile the cell formula when we already have a compiled formula. Task: [6395361](https://www.odoo.com/web#id=6395361&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
This update modernizes part of the grid view code to stay compatible with the next version of Odoo's interface framework. It preserves the expected keyboard navigation behavior, including correctly focusing the toggle button when users enter edit mode.
Original PR description
Replaced `useLayoutEffect` with `signal.ref` + `useEffect` because `useLayoutEffect` is deprecated in OWL3. The commented-out effect focused the toggle button when its DOM element became available, using an explicit dep array `[this.buttonRef.el]`. That dep only worked because the compat `useRef().el` getter untracks its underlying signal. Converting `buttonRef` to a real `signal.ref(HTMLButtonElement)` makes `useEffect` auto-subscribe to the ref signal: when edit mode is entered (button rendered under `t-if`) the ref updates, the effect re-runs, and the button is focused — no explicit dep array needed. The useLayoutEffect refactored in this PR had test coverage — below are some tests that failed when the effect was commented out, and are now passing: - `@web_grid/grid_cells/float_toggle_grid_cell/FloatToggleGridCell: keyboard navigation` see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2624596/build/116553766
The accounting reports code was updated to use the newer supported framework approach, reducing the risk of issues when Odoo moves to OWL3. A new automated test was added to confirm report filters continue to update correctly when switching reports.
Original PR description
Replaced `useLayoutEffect` with `useEffect` from `@odoo/owl` because `useLayoutEffect` is deprecated in OWL3. `useEffect` auto-tracks reactive reads inside the callback, so reading `this.controller.cachedFilterOptions?.report_id` directly in the effect body is sufficient to re-run when the report changes — no explicit dependency array is needed. When commenting out the useLayoutEffect there was no error, the code we refactored had NO TEST coverage. A test was written to ensure our fix was correct, and it was tested against the previous useLayoutEffect: - Passed with previous useLayoutEffect. - Failed with previous useLayoutEffect commented. - Passed with our OWL3 replacement.