Tuesday, December 9, 2025
20 changes · 18.0
Resolved issues and error corrections
This update corrects a critical issue where Swiss account translations were missing, specifically impacting payroll documents. The fix ensures all official payroll documents are consistently translated, preventing mixed language content and maintaining compliance. This improves the accuracy and professionalism of our Swiss accounting reports.
Original PR description
Some Swiss account translations were missing, mainly related to payroll. This resulted in payroll documents having mixed languages, which is not acceptable for official documents. opw-5343680 Forward-Port-Of: odoo/odoo#239001
This update fixes a bug where discounts applied to products tracked by lot were not appearing in the Point of Sale (POS) system. The fix adds the necessary discount line during the payment process, ensuring accurate pricing at the POS. This resolves a customer-reported issue impacting sales transactions.
Original PR description
When creating a sale order for a product, confirming it, Then, when paying for the order in the POS, the discount line is not available. Steps to reproduce: ------------------- * Create a product tracked by lot * Create a sale order for that same product and set the discount * Confirm the sale order * Pay the order in the POS > Observation: The discount line is not appearing. Why the fix: ------------ The customer applies the discount for the product, but it's not appearing in the POS. So I just added the discount line **Before Fix** <img width="485" height="202" alt="before_fix" src="https://github.com/user-attachments/assets/5c559569-8f89-4bfd-8fe8-5415b1236406" /> **After Fix** <img width="485" height="221" alt="after_fix" src="https://github.com/user-attachments/assets/e6aa7ea6-5ff9-4d66-ae56-d18ea25e2878" /> opw-5084170
This update resolves an issue where products with multiple identical attributes and optional products would cause website errors when adding to the cart. The fix ensures a more robust mapping of attributes, preventing configuration errors and allowing users to consistently add products to their carts. This improves the overall website stability and user experience.
Original PR description
Issue before this commit: ========================= When a product contains multiple attribute lines using the same attribute and also has optional products, attempting to add the product to the cart…
Issue before this commit:
=========================
When a product contains multiple attribute lines using the same attribute and
also has optional products, attempting to add the product to the cart from the
website resulted in a server error. The product configurator failed during
attribute-line processing, causing the Add to Cart button to crash.
Steps to Reproduce:
=========================
1. Install website_sale and enable product variants.
2. Create a product containing:
- Two or more attribute lines referencing the same attribute
- At least one optional product.
3. Publish the product on the website.
4. Go to the product page and click Add to Cart button.
Cause of the Issue:
=========================
The website product configurator assumes a one-to-one mapping between attribute
lines and their attributes.
When multiple attribute lines share the same attribute_id, the current mapping
logic builds an incomplete attribute map.
This causes a KeyError during configurator construction, leading to a error when
adding the product to the cart.
Related to this PR: https://github.com/odoo/odoo/pull/235170
With This Commit:
=========================
A safer attribute mapping mechanism is introduced, ensuring that each attribute
line even if sharing the same attribute always receives its own attribute data.
This prevents missing keys during configurator processing and allows products
with duplicate attribute lines and optional products to be added to the cart
without errors.
Steps To Reporduce: [Video Link](https://drive.google.com/file/d/1cKLNfJAOvp6IFTmoL4BtkGnZgIV7omta/view?usp=drive_link)
**opw-5361565**This update resolves an issue where the Czech VAT control statement incorrectly categorized invoices in foreign currency (specifically EUR). The fix ensures accurate reporting by correctly handling currency conversions and using the absolute value of the total amount for foreign currency transactions, improving the accuracy of VAT reporting for Czech businesses.
Original PR description
With l10n_cz_reports: - Create a currency exchange between CZK and EUR where the EUR is valued at least at twice the amount of CZK. - Create an invoice in EUR, with a line with price_unit 5000 and a tax. - In the CZ Tax Report, in the VAT control statement, the converted amount is found in section B.3, which contains received taxable supplies and provided payments up to CZK 10,000. However, the converted amount of the invoice in CZK is higher than 10,000. In `_report_custom_engine_control_statement`, the amount used to check whether the move should be included in this section uses `amount_total`, which in the case of foreign currency gives the wrong result. If the move is in a foreign currency the total is not in CZK so we have to use the absolute value of the signed total. opw-5080339
This update resolves an issue in the Swedish SIE import process where SHA512 hashing was not being correctly implemented. The fix ensures accurate data integrity during import, preventing potential data discrepancies and improving the reliability of the import functionality. This update is a critical fix for accurate financial reporting.
Original PR description
Forward-Port-Of: odoo/enterprise#101511
This update resolves an issue causing the Odoo scheduler to freeze in Firefox when sending multiple scheduled messages. The problem stemmed from an infinite loop triggered by reactivity on empty array slots. The fix prevents reactivity in these scenarios, improving stability and preventing user disruption.
Original PR description
**Steps to reproduce:** - (Firefox only) - Go to any record which uses a chatter (e.g. Contact) - Send message > Full composer > click the schedule message icon (lower right corner) - Schedule the…
**Steps to reproduce:**
- (Firefox only)
- Go to any record which uses a chatter (e.g. Contact)
- Send message > Full composer > click the schedule message icon (lower right corner)
- Schedule the message in the future and click send
- You should see now a post in the chatter indicating that the message will be sent
- Now click Send message and repeat the above steps again to schedule a second message
- Whole page will be freezed
- Reloading doesn't help
**Issue:**
Infinite loop in reactive callback on firefox.
The code gets stuck in
```js
for (const callback of [...callbacks]) {
clearReactivesForCallback(callback);
callback();
}
```
because of
```js
const sortProxy2 = reactive(recordProxy, function sortObserver() {
self.requestSort(record, fieldName);
});
this.fieldsSortProxy2.set(fieldName, sortProxy2);
```
which loops over `store._.ADD_QUEUE("sort", record, fieldName);`
(Forcing the `requestSort` only change the infinite loop into a recursion error)
The recomputation seems to be caused by `record[fieldName]` being an array filled with empty slots (previously deleted values). As to why it only happens on firefox, no idea, it's probably related to the design of the tracking on empty slots.
**Fix:**
Avoid reactivity when the value is an array with empty slots. The issue could also happen in other places (e.g. for the `computeProxy2`). Finding a better more reliable/generic fix would be great to avoid the issue on owl level.
related: https://github.com/odoo/odoo/commit/ba77db25c836cb692066cb9487842f7f683beaad
opw-5367371This update introduces a new tax calculation for Italian VAT returns related to RA Agenti withholding, specifically addressing a 23% rate applied to 20% of the base. The changes involve updating export logic and mapping tax rates to ensure accurate reporting of this withholding tax. This ensures compliance with Italian tax regulations.
Original PR description
This commit adds a new RA Agenti withholding tax for the case where 23% is applied on 20% of the base (effective –4.6%) and ensure it is exported using the 23% rate. Key changes: - Added new tax: –4.6% (23% su 20% RA Agenti) - Updated name and invoice label of the existing –11.5% tax - Updated EDI export logic to map –11.5% → 23% and –4.6% → 23% task-5258180
This update resolves issues related to how production splitting and inventory state calculations are handled, particularly concerning work orders and reservations. The changes ensure accurate state computations, preventing errors and improving the reliability of production tracking within the MRP module. This addresses a bug impacting production splitting and related inventory processes.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an inconsistency in how Odoo calculates rental prices based on time zones. Previously, using relativedelta with time-zoned dates resulted in incorrect price calculations. This change ensures that rental prices are consistently calculated regardless of the rental's start and end dates, addressing potential pricing discrepancies.
Original PR description
Relativedelta on UTC dates or time-zoned dates doesn't return the same result. In order to calculate consistent prices (price for 1 month in December = price for 1 month in January), we need to work on time-zoned dates. Example: Consider a website in UTC+1 (Brussels timezone DST off). And a rental from the 01/12/2025 to the 31/12/2025 = by design, from the 01/01/2025 00h00 (start_date) to the 31/12/2025 23h59 (end_date). Converted in UTC for the back-end, we have: from the 30/11/2025 23h00 to the 31/12/2025 22h59. relativedelta(end_date, start_date) = time between the 2 dates is calculated as follow: 30/11/2025 23h00 + 1 month = 30/12/2025 23h00 +23h59 = 31/12/2025 22h59. Time difference = 1 month, 23 hours, 59 minutes. Price = 2 months. Consider a second rental from the 01/01/2026 to the 31/01/2026. 31/12/2025 23h00 + 30 days = 30/01/2026 23h + 23h59 = 31/01/2026 22h59. Time difference = 30 days, 23 hours, 59 minutes. Price = 1 month. opw-5130762
This update resolves a potential memory issue that could occur during HR Timesheet installations on databases with many existing accounting records. The change ensures that new data fields are correctly initialized, preventing the system from running out of memory and improving installation speed and stability. This addresses a previous technical problem.
Original PR description
Description ----------- On databases with a large count of existing `account.analytic.line` records, installing modules like `hr_timesheet`, which adds compute stored or related stored fields to this model can trigger a memory error due to the volume of records that need to be recomputed. This commit creates the columns manually with the correct default value that is inferred from the state and implementation of said fields. Reference --------- opw-5234833 opw-5255382 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#239024
This update significantly speeds up Odoo's financial reports (Balance Sheet, P&L, Executive Summary) by caching pre-aggregated account balances. Previously, each report formula re-calculated these balances repeatedly, leading to slow performance. Now, a single calculation is stored and reused, dramatically reducing report generation times.
Original PR description
### Issue Large financial reports are slow to compute due to repeated re-aggregation of account_move_line balances for each formula, even when most formulas share the same base domain (usually…
### Issue
Large financial reports are slow to compute due to repeated re-aggregation of account_move_line balances for each formula, even when most formulas share the same base domain (usually filtered by account_id fields).
### Analysis
Each report line formula independently aggregates balances from account_move_line, even when their domains only differ on account_id-related fields such as account_id.account_type or account_id.non_trade.
This leads to redundant scanning and aggregation of the same dataset multiple times within a single report execution.
### Solution
Introduce a lightweight in-memory caching layer for aggregated balances by account_id, stored in self.env.cr.cache.
For each (options, date_scope) pair:
The report engine now computes once the mapping
{account_id: {'amt': total_balance, 'count_aml_lines': count}}.
This mapping is stored in the cursor cache and reused across all formulas whose domains filter exclusively on account_id fields.
A small domain transformation step allows AML domains based on account_id.* fields to be evaluated directly against the cached account aggregates.
This approach avoids redundant SQL aggregation, remains fully read-only (no database writes), and is safe for execution on read replicas.
### Benchmarks
Profiling get_report_information_readonly on different reports. Database has ~11.6 million account_move_lines, 305 account_accounts, and 16 account_types
| Report Name | Before | After | % Speed Up |
| --- |---|---|---|
| Balance Sheet | 35s | 6.2s | ~550% |
| Profit and Loss | 7.2 | 2.1 | ~300% |
| Executive Summary | 24s | 6.3 | ~400% |
### References
opw-5130725This update resolves an issue in the Hong Kong payroll system where the default account for net salary payments was incorrect. The change implements a new 'Salaries & Wages Payable' account, ensuring accurate payslip payments and resolving payment problems. This improves the reliability of payroll processing for Hong Kong businesses.
Original PR description
Fixes the default account for NET salary rules in the Hong Kong payroll, which is using the wrong account type and causes issues when trying to pay payslips. It is replaced by a new Salaries & Wages Payable account, and we also set it for the structures other than 'Monthly Pay' task-5042786
This update resolves an issue where loyalty reward rules using 'not ilike' operators weren't functioning correctly. The fix corrects a double negation problem within the system's domain processing, ensuring that rewards are applied as intended when filtering products based on exclusion criteria. This prevents rewards from being missed when using 'not ilike' domains.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a loyalty program; 2. Create a reward; 3. Add a Product domain to the reward containing the `not ilike` operator; 4. Load the POS; 5. Try to trigger…
Versions
--------
- 18.0+
Steps
-----
1. Create a loyalty program;
2. Create a reward;
3. Add a Product domain to the reward containing the `not ilike` operator;
4. Load the POS;
5. Try to trigger the Loyalty program;
6. The Reward is not applied when the domain is satisfied
Issue
-----
Loyalty Program rewards containing `not ilike`-based product domains are not applied when they should.
Cause
-----
The `_replace_ilike_with_in` function in loyalty_reward.py converts the `ilike` and `not ilike` operators by first fetching the records that very the domain with the operator used, and then by replacing the domain by `in` or `not in` with the returned records ids. This is problematic as in the case of `not ilike`, it leads to a double negation.
Example
-----
For `ilike`: `['categ_id', 'ilike', 'service']`
-> Search for all categories that contain "service": `_search([('display_name', 'ilike', 'service')])`
-> Return new domain `['categ_id', 'in', matching_ids]`
Which is correct.
For `not ilike`: `['categ_id', 'not ilike', 'service']`
-> Search for all categories that **do not contain** "service": `_search([('display_name', 'not ilike', 'service')])`
-> Return new domain `['categ_id', 'not in', matching_ids]`
Which is incorrect, as the matching_ids are already the ids that are not like "service". (i.e., *categ_id not in the categories that do not contain "service"* <=> *categ_id in the categories that contain "service"*, opposite of what is expected.)
Solution
--------
1. Perform the initial search with `ilike` for both operators
opw-5182818
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update fixes a confusing issue on Odoo POS receipts where all tax amounts (CGST, SGST, IGST) were displayed together. Now, receipts accurately show only the relevant tax column – either CGST+SGST or IGST – based on the transaction, improving clarity for users and ensuring accurate reporting.
Original PR description
Description of the issue/feature this PR addresses: - The POS receipt shows CGST, SGST, and IGST together, even when IGST is applicable. - This is incorrect because only CGST+SGST or IGST should be…
Description of the issue/feature this PR addresses: - The POS receipt shows CGST, SGST, and IGST together, even when IGST is applicable. - This is incorrect because only CGST+SGST or IGST should be displayed, not all three. Current behavior before PR: - The receipt always displays CGST, SGST, and IGST columns at the same time. <img width="250" height="400" alt="image" src="https://github.com/user-attachments/assets/5c8487c7-c497-4c82-ad80-8cf0e98fbf38" /> Desired behavior after PR is merged: - The receipt shows only the correct tax columns based on the transaction: - Shows CGST and SGST when GST applies. - Shows IGST when IGST applies. <img width="250" height="400" alt="image" src="https://github.com/user-attachments/assets/68d2fb58-9e15-4861-a71f-ccb2d978e544" /> Changes implemented in this commit: - Added `t-if="l10n_in_hsn_summary.has_gst"` to CGST and SGST headers. - Added the same condition to CGST and SGST values in the item rows. task-5268935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where Turkish language translations weren't properly applied after installing the 'l10n_tr_nilvera' module. The fix ensures that all module translations are updated, providing accurate Turkish language support for new databases and company configurations. This improves the user experience for Turkish-speaking customers.
Original PR description
### Issue: When installing "l10n_tr_nilvera" on a new DB the Turkish language is installed but the translation of previously installed modules are not updated. ### Steps to reproduce: - Install 'l10n_tr_nilvera' and switch to a Saudi company - Check the view "report_invoice_document" - Click the translation icon on the view - No Turkish translations are loaded ### Cause: When installing "l10n_gcc_invoice" the Arabic language is installed ([src](https://github.com/odoo/odoo/blob/70404624d7ea6f971182cbe4f4fe8fc064d2afd8/addons/l10n_gcc_invoice/__init__.py#L4-L5)). But the method [`_activate_lang()`](https://github.com/odoo/odoo/blob/70404624d7ea6f971182cbe4f4fe8fc064d2afd8/odoo/addons/base/models/res_lang.py#L161-L169) only activates the language, it does not update the translations. ### Solution: Create a new method that activate the language and calls `_update_translations()` on the installed modules. opw-5219783
This update fixes an issue where invoice totals didn't update correctly when changing the unit price or product. Previously, changes required a full save of the invoice. Now, the totals dynamically adjust immediately when the unit price or product is modified, ensuring accurate calculations.
Original PR description
**Steps to reproduce:** - Install Accounting - Create an invoice with an invoice line - Save the invoice - Change the unit price => The totals should change - Change the product => The unit price and…
**Steps to reproduce:** - Install Accounting - Create an invoice with an invoice line - Save the invoice - Change the unit price => The totals should change - Change the product => The unit price and the totals should change - Change the unit price again **Issue:** After this point, the totals don't change anymore, even if the unit price is changed several times. Only saving the form will adapt the totals correctly. **Cause:** When changing the unit price the first time, a "price_unit "key is added in the onchange values. When changing the product, a "product_id" key is added after the price key. Changing the product triggers an onchange of the price with the price of the new product. However, when the price is changed again, as the "price_unit" key already exists, it's reused and its position is still before "product_id" key even if it should be computed after. This order results in the use of the price of the second product instead of the one entered manually when computing the "tax_totals". **Solution:** If "product_id" and "price_unit" are the values of the onchange method, the list of values is reordered to make sure that "product_id" is computed first. opw-5012125 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232684
This update resolves a problem where invoices generated in Arabic were sometimes printed incorrectly, with missing logos or repeated headers. The fix reduces the number of invoices processed at once, allowing the printing software to render them correctly. This ensures consistent and professional invoice output for all customers.
Original PR description
Repro steps: 1. Create a customer whose language is Arabic 2. Create 16 or more invoices for that customer 3. Send these invoices together all at once Issue: PDFs generated for the invoices are strange, some have missing logo in the header, while others have the header repeated multiple times on the page. Root cause: wkhtmltopdf does not have enough time to render all these PDFs at once, so it fails to render them properly leading to these half-rendered PDFs. Solution: This commit solves this issue by reducing the number of invoices that the cron processes at once from 20 to only 10 (the default of the function _cron_account_move_send). This would ensure that wkhtmltopdf has enough time to process and render a batch of invoices at once. opw-4997495 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update addresses a change in Facebook's data reporting, specifically regarding audience trends. Due to a rapid response needed, the team temporarily bypassed verification of 'unfollows' to quickly resolve the issue. Now, the system utilizes total page follows to accurately reflect audience changes, ensuring reliable Facebook integration data.
Original PR description
Bug === Facebook deprecated some of the endpoints related to statistics https://developers.facebook.com/docs/platforminsights/page/deprecated-metrics We fixed all metric except the audience trend,…
Bug === Facebook deprecated some of the endpoints related to statistics https://developers.facebook.com/docs/platforminsights/page/deprecated-metrics We fixed all metric except the audience trend, because we needed a fix rapidly, and we wasn't sure about unfollow. And indeed, `page_daily_follows` only count for positive value, unlike the old `page_fan_adds` / `page_fan_removes`, and there's no equivalent of `page_fan_removes`... Example of data for a month: ``` page_follows 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 page_daily_follows 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 page_follows 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 page_daily_follows 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ``` So we now use `page_follows`, so the total value at a given time, and we look for the newest and oldest value (note that if we could do the same for `page_post_engagements`, then we could just make 2 APIs calls for the year stat). Task-5353390 Forward-Port-Of: odoo/enterprise#100275
This update resolves a bug where the OCR process incorrectly assigned foreign currencies to expense reports, particularly when linked to products with standard prices. Now, users can correct the total amount after the OCR, and the system prevents the currency from being locked, ensuring accurate reimbursements. This improves the reliability of expense reporting.
Original PR description
Fixes a bug where the OCR would sometimes put a foreign currency on an expense with a product having a cost. Making it impossible to switch back to the company currency (because the currency cannot be changed). This also allows the user to change the total amount after the OCR pass, so it can be corrected if needed task-4873236 Forward-Port-Of: odoo/enterprise#89093
This update corrects a bug in the sale loyalty discount system. Previously, discounts weren't accurately calculating based on the quantity of each item, leading to incorrect discount amounts. The change ensures that the cheapest line is discounted correctly, aligning with discount limits and improving accuracy.
Original PR description
Discounts based on the cheapest line were not accounting for the quantity on the line and this was causing issues with the computations when using a maximum discount amount. Changing the discountable value to be a ratio of the quantity on the line allows the cheapest product to be discounted at the correct amount without messing with the discount factor. opw-4998557 Forward-Port-Of: odoo/odoo#222564