Daily updates from Odoo
Wednesday, August 12, 2026
22 changes
2 changes
Enhancements to existing features
Document attachment link calculations have been optimized to reduce unnecessary searches and improve performance. This should make document-related operations feel faster, especially where many attachments are involved, without changing user-facing features.
Original PR description
* Prefetching attachment_ids in sudo allows to limit the scope of the documents search * Removing the location filter on the document, not worth the performance hit. Follow-up of Task-5882406 Forward-Port-Of: odoo/enterprise#127062
We name threads to get actual names instead of `Thread-<n>` in tracebacks. Before: ```python ERROR ? odoo.addons.iot_drivers.exception_logger: Unhandled exception in thread Thread-11 Traceback (most recent call last): ... raise Exception("in display driver") ``` After: ```python ERROR ? odoo.addons.iot_drivers.exception_logger: Unhandled exception in thread DisplayDriver(HDMI-A-1) Traceback (most recent call last): ... raise Exception("in display driver") ```
Original PR description
We name threads to get actual names instead of
`Thread-<n>` in tracebacks.
Before:
```python
ERROR ? odoo.addons.iot_drivers.exception_logger: Unhandled exception in thread Thread-11
Traceback (most recent call last):
...
raise Exception("in display driver")
```
After:
```python
ERROR ? odoo.addons.iot_drivers.exception_logger: Unhandled exception in thread DisplayDriver(HDMI-A-1)
Traceback (most recent call last):
...
raise Exception("in display driver")
```1 change
Enhancements to existing features
Before this commit, when importing and invoice/bill, we predicted the invoice line account based on previous invoices/bills. If the predicted account had default tax, it was ignored during tax matching. With this commit, first checks whether the predicted account has a default tax. If it finds one that matches the tax percentage from the imported XML, that tax is applied. Otherwise, or if the account has no default tax, the existing tax matching logic is used. task-6345661 Forward-Po
Original PR description
Before this commit, when importing and invoice/bill, we predicted the invoice line account based on previous invoices/bills. If the predicted account had default tax, it was ignored during tax matching. With this commit, first checks whether the predicted account has a default tax. If it finds one that matches the tax percentage from the imported XML, that tax is applied. Otherwise, or if the account has no default tax, the existing tax matching logic is used. task-6345661 Forward-Port-Of: odoo/odoo#281424 Forward-Port-Of: odoo/odoo#279940
2 changes
Enhancements to existing features
Budget reports now load much faster by changing how budget lines are matched to accounting and purchase data. This reduces long waits and makes the report usable on databases with large volumes of budget and analytical records.
Original PR description
**Description:** While loading the budget report, the bad queries are created by ```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes the budget report unusable. **Root cause:**…
**Description:**
While loading the budget report, the bad queries are created by
```def _get_aal_query()``` and ```def _get_pol_query()``` function, makes
the budget report unusable.
**Root cause:**
Instead of doing a hash join while searching the record,
the OR statement in the Left Join in the condition
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```
creates a nested for loop that compares everything single aal to bl,
this causes a significant performance issue as the number of the
number of check will be the the number aal * bl,
if a database has a 70k aal and 20k bl, both numbers are not large
but it will cause a 70k * 20k search which is more than a billion.
**Fix**:
There are some refactors made in this PR.
_First_, separate out the Q1.
In order to find the aal that has no bl connects to it.
Doing a search to find the aals that have bl and then subtract them from all aals.
_Second_, Instead of doing a nested loop for by using
```(%(bl)s IS NULL OR %(a)s = %(bl)s)```,
originally we will have do something like
```
JOIN budget_line bl
ON (bl.x_plan2_id IS NULL OR aal.x_plan2_id = bl.x_plan2_id)
AND (bl.x_plan3_id IS NULL OR aal.x_plan3_id = bl.x_plan3_id)
AND (bl.x_plan4_id IS NULL OR aal.x_plan4_id = bl.x_plan4_id)
```
Assuming each bl has three plans ```x_plan2_id```, ```x_plan3_id```, ```x_plan4_id```
Grouping the bl base on whether a specific plan is set, (i.e. shapes)
we can skip the ```IS NULL OR``` because we already know which plan
is null and do the hash join directly.
For example, the shapes will be a dictionary with a key of a tuple of booleans
based on whether a plan is set or not and the value is a list of bl_id.
```
{
(True, False, False): [1, 2],
(False, True, True): [3, 4],
(False, False, False): [5],
}
```
we can end up doing something like
```
JOIN budget_line bl
ON bl.id = ANY(ARRAY[3,4])
AND aal.x_plan3_id = bl.x_plan3_id AND aal.x_plan4_id = bl.x_plan4_id
```
which is way more faster.
---
The benchmark is made locally from this client's database which contains
69k aal, 23k bl, 6829 pol and 3 plans for aal and bl.
|Record count |Time before|Time after|
|--------------------------------------------------|-----------------|---------------|
|69k aal, 23k bl, 6829 pol, 3 plans |70.04s |4.6s |
Dalibo:
Before:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/8h3d4e89aaf9f3d4
Overall grand total by company:
https://explain.dalibo.com/plan/445g1f9caf4923e2
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/53a138ca50b2a7c4
Overall grand total by plan:
https://explain.dalibo.com/plan/hdbe169ddc7g5785
After:
Month-over-month grand total by company:
https://explain.dalibo.com/plan/hcc86c801e6872bf
Overall grand total by company:
https://explain.dalibo.com/plan/69b2421a3581f98h
Month-over-month grand total by plan:
https://explain.dalibo.com/plan/a88f398bbbch3148
Overall grand total by plan:
https://explain.dalibo.com/plan/1gg749ae7ab1553c
opw-6345552
Forward-Port-Of: odoo/enterprise#127405
Forward-Port-Of: odoo/enterprise#124161Before this commit, when importing and invoice/bill, we predicted the invoice line account based on previous invoices/bills. If the predicted account had default tax, it was ignored during tax matching. With this commit, first checks whether the predicted account has a default tax. If it finds one that matches the tax percentage from the imported XML, that tax is applied. Otherwise, or if the account has no default tax, the existing tax matching logic is used. task-6345661 Forward-Po
Original PR description
Before this commit, when importing and invoice/bill, we predicted the invoice line account based on previous invoices/bills. If the predicted account had default tax, it was ignored during tax matching. With this commit, first checks whether the predicted account has a default tax. If it finds one that matches the tax percentage from the imported XML, that tax is applied. Otherwise, or if the account has no default tax, the existing tax matching logic is used. task-6345661 Forward-Port-Of: odoo/odoo#281424 Forward-Port-Of: odoo/odoo#279940
2 changes
Enhancements to existing features
Before this commit, when importing and invoice/bill, we predicted the invoice line account based on previous invoices/bills. If the predicted account had default tax, it was ignored during tax matching. With this commit, first checks whether the predicted account has a default tax. If it finds one that matches the tax percentage from the imported XML, that tax is applied. Otherwise, or if the account has no default tax, the existing tax matching logic is used. task-6345661 Forward-Po
Original PR description
Before this commit, when importing and invoice/bill, we predicted the invoice line account based on previous invoices/bills. If the predicted account had default tax, it was ignored during tax matching. With this commit, first checks whether the predicted account has a default tax. If it finds one that matches the tax percentage from the imported XML, that tax is applied. Otherwise, or if the account has no default tax, the existing tax matching logic is used. task-6345661 Forward-Port-Of: odoo/odoo#281424 Forward-Port-Of: odoo/odoo#279940
This commit adds a "Reload Data" button to the traceback dialog for PWA applications. When clicked, the user is asked to confirm the action. Once confirmed, all locally stored browser data is cleared, allowing the POS to recover from errors caused by corrupted or outdated local data. task-6388234 Forward-Port-Of: odoo/odoo#276559
Original PR description
This commit adds a "Reload Data" button to the traceback dialog for PWA applications. When clicked, the user is asked to confirm the action. Once confirmed, all locally stored browser data is cleared, allowing the POS to recover from errors caused by corrupted or outdated local data. task-6388234 Forward-Port-Of: odoo/odoo#276559
14 changes
Enhancements to existing features
The Peru localization tests were updated to match revised default accounts introduced for smoother onboarding. This helps keep automated checks aligned with the current setup and reduces false failures during validation.
Original PR description
Purpose: Default accounts were updated for an improved onboarding process, which caused some tests to be outdated. Update the tests to align with the account changes. task-6221374
Indian GSTR-1 report exports now handle large accounting datasets much faster and with far less memory. This reduces the risk of export failures for high-volume businesses and makes compliance reporting more reliable.
Original PR description
Current Implementation: ======================= The current implementation of _get_l10n_in_gstr1_json relies on multiple iterations over ORM recordsets. Since the ORM loads multiple fields rather…
Current Implementation: ======================= The current implementation of _get_l10n_in_gstr1_json relies on multiple iterations over ORM recordsets. Since the ORM loads multiple fields rather than only the required fields, memory consumption grows significantly for large datasets (around 700 MB for 150K account move lines). Additionally, the method builds a single large dictionary from _get_tax_details that is tailored for the Indian GST reporting logic. Constructing and holding this intermediate data structure further increases memory usage. The combination of repeated Python loops, ORM overhead, and the large intermediate dictionary results in high execution time and memory consumption, causing the process to exceed the available time and memory limits for large exports. Solution: ========= Instead of processing tax details through the ORM, create a temporary table containing the GST tax details and query this subset directly for each GSTR-1 subsection. This approach bypasses the ORM, fetching only the required columns instead of entire records. Eliminates the need to build the large _get_tax_details dictionary. Reduces the number of Python-side iterations and intermediate data structures. Pushes the data aggregation and filtering to SQL, where it is more efficient. Restricts Python's responsibility to formatting the final JSON output. This significantly reduces memory usage, improves execution speed, and makes the implementation simpler and easier to maintain. Benchmark Performance Results: ============================== ```text +-----------+-------------+----------------------+------------------+ | Size | Parameter | Current Version | IMPROVED SQL + | | | | | Indian Reports | +-----------+-------------+----------------------+------------------+ | 150K AMLs | Time | 28.19s | 2.18s | | +-------------+----------------------+------------------+ | | Peak Memory | 711 MB | 34.7 MB | +-----------+-------------+----------------------+------------------+ | 250K AMLs | Time | 64s | 3.68s | | +-------------+----------------------+------------------+ | | Peak Memory | 1.4 GB | 58.5 MB | +-----------+-------------+----------------------+------------------+ | 500K AMLs | Time | 208s | 7.33s | | +-------------+----------------------+------------------+ | | Peak Memory | 2.7 GB | 114.8 MB | +-----------+-------------+----------------------+------------------+ | 1M AMLs | Time | Memory Limit (7 GB+) | 15.07s | | +-------------+----------------------+------------------+ | | Peak Memory | Memory Limit (7 GB+) | 230.7 MB | +-----------+-------------+----------------------+------------------+ | 2M AMLs | Time | Memory Limit (7 GB+) | 28.20s | | +-------------+----------------------+------------------+ | | Peak Memory | Memory Limit (7 GB+) | 461.4 MB | +-----------+-------------+----------------------+------------------+ ``` ref - https://drive.google.com/drive/folders/10I8gJmGgZVAMW8te_GFg5lleTUW1Nku1?usp=drive_link -------------------------- task-3941950 Community PR - https://github.com/odoo/odoo/pull/274381
The Master Production Schedule forecast wizard is now easier to use when updating forecasts for one or many products. Users can start with the current period prefilled, see all forecasting basis options, and apply the same update settings across multiple selected products at once.
Original PR description
This commit improves the Master Production Schedule forecast suggestion wizard with the following enhancements: - Prefill current period when opening wizard from product - Show all "Based On" options even when a specific period is selected (Previously hidden when period was set) - Replace "Toggle Indirect Demand" with "Update Forecast" in Actions menu - Add multi-product "Update Forecast" wizard for bulk forecast updates - Shows product count instead of product selector - Preview calculation based on first product - Applies settings to all selected products simultaneously
Starting a work order from the list view now records time under the employees assigned to that work order instead of always using the currently logged-in user. If no employee is assigned, the system still falls back to the logged-in user, helping keep production time records accurate without disrupting existing workflows.
Original PR description
This commit changes the behavior of starting a work order from the `mrp_workorder` tree view in terms of the employee(s) who perform(s) the time logs of the workorder. Previosuly, the logged in user was always used to perform these time logs, irrespective of the assigned employees of the workorder. This commit uses the assigned employees instead and fallbacks to the logged-in user in case there was no assigned employee. Task-4105643
Saudi payroll now allows companies to set a threshold for unpaid leave days that should be excluded from end-of-service benefit calculations. This improves compliance and accuracy by ensuring extended unpaid absences are handled consistently in employee benefit reports.
Original PR description
[IMP] l10n_sa_hr_payroll: exclude unpaid days from EOS New field is added to company and company settings l10n_sa_unpaid_leave_eos_threshold, unpaid holidays above this threshold should be excluded from EOS calculation Instead of using function _l10n_sa_get_eosb_compensation in salary rule python amount compute, we put the function directly to the salary rule's itself. EOS benefit wizard is changed because it was using the function _l10n_sa_get_eosb_compensation and now it uses the salary rule directly. Test is written to test the implemented functionality by testing the EOS benefit report for different scenarios. task - 6393974
Belgian payroll now automatically carries forward and recovers negative net salary amounts through payslip rules instead of relying on manual reporting. This reduces manual follow-up for payroll teams and adds targeted warnings when unrecovered amounts remain at year-end or employee departure.
Original PR description
Previously, payslips with negative net amounts relied on a manual reporting action (`action_report_negative_net_amount`) and a generic dashboard warning. This commit removes the legacy negative net reporting mechanism and replaces it with an automated salary-rule-based net recovery process in Belgian payroll: - Removed legacy `action_report_negative_net_amount`, warning helper, and `hr_payroll_warning_negative_net_to_report` record from `hr_payroll`. - Added `NET_TO_RECOVER` and `NET_ALREADY_RECOVERED` salary rules to automatically offset negative net salary and deduct prior debt. - Added `_get_net_to_recover_amount` helper method on `hr.payslip` to calculate and apply accumulated debt recovery across payslips. - Overrode `action_payslip_done` to automatically mark payslips with net amount <= 0 as 'paid'. - Added a Belgian payroll warning for December or departure payslips when an unrecovered net amount remains. Task: 6413612
Indian GST reporting now lets businesses with turnover below 5 crore choose whether to include HSN details for B2C transactions. A new setting allows users to turn this reporting on or off, helping them align reports with the updated GSTIN rules.
Original PR description
The GSTIN has updated the rules for B2C HSN reporting. Now it has become optional for businesses having a turnover of less than 5 Cr. This improvement aims to integrate this change into our system by providing a boolean in settings. The user can switch on/off the reporting mechanism using this boolean. task-6097595 Community PR - https://github.com/odoo/odoo/pull/269014
Map route calculations are no longer enabled by default across field service planning views. Routing is now limited to the Maps and Live Map menus, helping reduce unnecessary Mapbox token usage and related customer costs.
Original PR description
Currently, the map view calculates routing by default whenever Mapbox is enabled. This ends up consuming unnecessary tokens (which cost the customer money) in views where routing isn't actually needed or relevant. To prevent this waste, we are turning off the default routing on the main map view. Moving forward, the routing feature is only explicitly enabled in the "Maps" and "Live Map" menus, where seeing the route actually makes sense for the user. task-6351070
This update removes an unused setup step in the AI chat area. It simplifies the underlying code without changing how users interact with the product.
Original PR description
This commit removes a `useSubEnv` that defines `expandedFromAiChat` which is never used.
When a bank statement line is mistakenly matched and then unreconciled, the system now removes the related bank account if it is not used elsewhere. This helps keep accounting records cleaner while still letting users manually decide whether to remove the partner before reconciling again.
Original PR description
When a bank statement line was matched with a move by mistake and the user unreconcile it, the bank account should be deleted if not used anywhere else. We chose not to remove the partner from the bank statement line automatically and let the user do it manually before reconcile again task-6285463
Manufacturing teams can now include draft manufacturing orders when planning work orders, giving schedulers earlier visibility into upcoming production needs. This helps teams reserve capacity sooner and align labor or cost reporting before orders are fully confirmed.
Original PR description
task: 6365342
Belgian payroll now lets HR decide whether a union meeting absence should grant a meal voucher on a case-by-case basis. This supports situations where eligibility depends on the employee’s representative status and the meeting type, improving payroll accuracy.
Original PR description
Whether a union meeting (LEAVE249) grants a meal voucher depends on the employee being an elected representative and on the type of meeting, so it cannot be decided by the time type alone. Declare MEAL_VOUCHER as an optional category of LEAVE249, letting the HR user tick it per time off. task-6356965
Document records now determine their linked attachments more efficiently by narrowing searches and avoiding an expensive location check. This should improve performance in document-heavy workflows without changing what users do day to day.
Original PR description
* Prefetching attachment_ids in sudo allows to limit the scope of the documents search * Removing the location filter on the document, not worth the performance hit. Follow-up of Task-5882406 Forward-Port-Of: odoo/enterprise#127062
The Indian reports module now includes document type 2 for GSTR-1 document summaries, covering invoices for inward supplies from unregistered persons. This helps businesses report self-invoice data required under Table 13 of GSTR rules.
Original PR description
with this commit:- - We added document type '2' which states 'Invoice for Inward Supply from Unregistered Person' for gstr1 document summary. - This is required to sent self invoice data to the government as per Table-13 of GSTR act. task-6259173
1 change
Enhancements to existing features
WIP --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
WIP --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr