Daily updates from Odoo
Wednesday, June 10, 2026
323 changes
3 changes
Resolved issues and error corrections
This update resolves a performance issue within the tests for the 'Discuss' feature in Odoo. The fix optimizes a database query, resulting in faster test execution times. This improves the overall stability and reliability of the Odoo platform.
Original PR description
runbot-243772 https://github.com/odoo/enterprise/pull/119886 Forward-Port-Of: odoo/odoo#269111
This update addresses a performance issue within the Discuss module, specifically related to how it counts conversations. The change optimizes the query, resulting in faster response times and a smoother user experience. This improvement ensures the Discuss feature remains efficient for all users.
Original PR description
runbot-243772 https://github.com/odoo/odoo/pull/269111 Forward-Port-Of: odoo/enterprise#119886
This update fixes a translation error in Odoo's Argentine localization (l10n_ar) module, ensuring fiscal position names accurately reflect their purpose. Previously, a confusing translation led to duplicate entries, which this change resolves, streamlining the system and improving data clarity.
Original PR description
### Description of the issue/feature this PR addresses: Fix fiscal position spanish translation to match with its real purpose. ### Current behavior before PR: * We have a fiscal position name that does not match with its purpose: Represent the local operations inside argentina (country: Argentina) but the name is " Purchases / Sales abroad" * Two fiscal positions have the same translation value and this is confusing ### Desired behavior after PR is merged: * we do not have duplicated fiscal position anymore * Domestic fiscal position is taged with the correct name --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264257 Forward-Port-Of: odoo/odoo#248462
7 changes
Resolved issues and error corrections
This update corrects a technical error within the Odoo Enterprise planning module. The issue stemmed from how default values were retrieved, which could result in an error when multiple planning slots were accessed simultaneously. This fix ensures the system functions reliably and prevents potential disruptions to planning processes.
Original PR description
`self` could be non-singletion recordset ``` (Pdb) p self.default_get(['repeat_interval']) *** ValueError: Expected singleton: planning.slot(227, 174) ``` See: 689a15b46c85774f3ab9ee4b9173a549c2ce1abf
This update addresses a recurring problem where payments at self-order kiosks were getting stuck when using the IoT Worldline terminal. The fix allows the system to correctly handle terminal disconnections and provides more specific error messages based on the terminal's feedback, improving the overall payment experience. This prevents frustrating delays for customers.
Original PR description
This PR fixes some payments in pos kiosk being stuck with iot worldline terminal. It allows to succesfully interpret when the terminal is disconnected and adapts the error messages to the information received fromthe terminal instead of the current generic "An error has occurred" enterprise: https://github.com/odoo/enterprise/pull/107709 task-5946033 Forward-Port-Of: odoo/odoo#249582 Forward-Port-Of: odoo/odoo#249101
This update significantly speeds up the Inventory Valuation report by reducing the number of products processed. Previously, the report strained system resources, but now it focuses only on products with stock, dramatically improving performance – particularly for large catalogs. This change ensures the report runs efficiently and reliably.
Original PR description
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only…
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only products that have stock (under the same valuation context that total_value uses) or that are lot-valuated, and feeds that smaller set into stock_value and stock_accounting_value. For historical (at_date) reports the search runs with to_date in context so qty_available is scoped to that date. _get_accounts_by_product() also switches to search_fetch so only categ_id is loaded upfront. Benchmarks were measured on a customer database restore with ~360k storable products. After filtering, ~2.5k products feed into the valuation today and ~2.2k for a historical date. Benchmark opening Inventory Valuation report (Accounting) | Date | Before | After | Speed up | |------------|--------|--------|----------| | Today | ~88s | ~2s | 41x | | Historical | ~245s | ~173s | 1.4x | The historical improvement is more modest because stock_value still has to compute total_value at the historical date for the remaining products, which traces SVL/stock.move history; the filter eliminates the dominant per-product overhead today but only the tail in the historical case. 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 Forward-Port-Of: odoo/odoo#265931 Forward-Port-Of: odoo/odoo#254010
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The change prevents this by validating the product setup, ensuring a subscription plan is present before allowing the recurring product to be added, improving order stability.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#119955 Forward-Port-Of: odoo/enterprise#107691
This update corrects a bug where products without lot/serial tracking incorrectly displayed expiration warnings. The change ensures that products tracked by quantity don't trigger the expiration flow, aligning with intended usage. This prevents unnecessary alerts and streamlines product management.
Original PR description
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup…
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup since from saas-18.4 there is a line where if `ml.removal_date <= datetime.datetime.now()` the picking is expired. So, if the product previously met these conditions, it will still be able to enter this flow. And since this product doesn't use a lot_id it displays “You are going to deliver the product False, False which is expired or should at least be removed from stock” What should happen: When a product is not tracked, use_expiration_date should be False as expiration dates are intended to be managed through lots or serial numbers. Steps to reproduce 1. Enable Product Expiry. 2. Create a storable product with: - Tracking: By Lots - Use Expiration Date: enabled - Set a value greater than 0 for removal_time 3. Change the product tracking to By Quantity. 4. Create and validate a receipt for the product. Related Tickets: opw-6255673 Forward-Port-Of: odoo/odoo#268135
This update corrects a technical issue with how Odoo validates cardholder addresses for Stripe payments. The system was incorrectly using an outdated ISO 3166-2 standard for state codes, causing failures for US addresses. This fix ensures accurate address validation and avoids potential payment processing problems.
Original PR description
Stripe says that address.state is "State, county, province, or region (ISO 3166-2)". There didn't seems to be any issues since it seems that it's not checked for the EU. However, this is still wrong and could raise an issue if Stripe decide to start checking them. Also, with the US coming soon, it's being checked and failed. Forward-Port-Of: odoo/enterprise#114480
This update corrects a bug in how leads are assigned to sales teams, ensuring a more equitable distribution of leads. Previously, team members created earlier received a disproportionate number of leads, particularly when quotas were equal. The fix introduces random tie-breaking to prevent this bias and ensure fair lead assignment.
Original PR description
_assign_and_convert_leads() is biased towards team members created earlier because they're ordered by create_date, id. When members have equal quota, the round-robin order falls back to the order of the team members. If the amount of leads distributed across the team is not a multiple of the team size, then the oldest members will get more leads assigned. This advantage repeats each time the cron runs and can add up to a big difference, the provided test case ends up assigning all 30 leads to the more senior member without the fix. Note that the lead_day_count field used in _get_assignment_quota() doesn't solve the problem. It helps to balance leads assigned in the same 24 hour window, but because the same senior person always goes first inside one of those windows, they will always get more leads assigned to them. To fix it we break ties in the quota randomly. task-6119168 Forward-Port-Of: odoo/odoo#268716 Forward-Port-Of: odoo/odoo#259775
1 change
Resolved issues and error corrections
This change resolves an issue where extremely long invoice reference strings in the general ledger report were causing wkhtmltopdf to generate bloated PDF files. By limiting the length of the reference string, we prevent the PDF from becoming excessively large and ensure reports generate reliably. This improves report performance and avoids system errors related to file descriptor limits.
Original PR description
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single…
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single invoice, the ref can become extremely long, e.g.: INV/2026/00001 (S12123, S12152, S12159, S12140, S12165, S12161, S12162, S12110, S12099, S12124, S12145, S12128, S12114, S12131, S12097, S12185, S12154, S12133, S12190, S12118, S12116, S12102, S12155, S12153, S12158, S12150, S12100, S12142, S12121, S12122, S12111, S12187, S12172, S12177, S12095, S12117, S12144, S12137, S12092, S12138, S12186, S12182, S12112, S12148, S12183, S12101, S12178, S12119, S12169, S12115, S12146, S12093, S12126, S12160, S12163, S12129, S12098, S12151, S12096, S12174, S12120, S12130, S12147, S12180, S12191, S12164, S12141, S12105, S12136, S12139, S12109, S12106, S12104, S12103, S12175, S12179, S12188, S12113, S12173, S12167, S12171, S12134, S12094, S12184, S12166, S12170, S12125, S12135, S12143, S12176, S12189, S12156, S12181, S12107, S12157, S12132, S12149, S12127, S12108, S12168...) Because the length of the account.report.line is unchecked in account_general_ledger.py label builder, the pdf can clog to one or two account.report.lines per page, skyrocketing the pdf page length. As wkhtmltopdf processes the report from html to pdf it makes a system call openat() to the /tmp/report.footer.tmp.x.html file for EACH page of the pdf. You can see the TODO comment in the spoolTo function in wkhtmltopdf (both in Odoo and the original repo) saying that the header and footer need to be freed, on each page processing, not just null pointed. https://github.com/odoo/wkhtmltopdf/blob/2c884bd1545b8a639847de22f24754ee5a6fc44c/src/lib/pdfconverter.cc#L794 I verified that that the number of openat calls to the /tmp/report.footer.tmp.x.html file equals the exact number of pages in the pdf to be generated if the report HAD generated successfully by setting the footer input into _run_wkhtmltopdf to None, generating the report without footers, then separately running an strace on wkhtmltopdf when the report fails to generate. See related ticket linked at bottom. The linux machine used on sh instances has a ulimit -n of 1024 file descriptors. Because the footer file descriptors accumulate, once a pdf has about 1010+ pages (~a dozen fd's are allocated for other purposes), over 1024 file descriptors are opened and the system fails with: Wkhtmltopdf failed (error code: -6). Message: QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe Since wkhtmltopdf is archived and Odoo has a replacement in development, I suggest that we limit the display_name of the account.report.line to 200 to keep the bloat minimized, preventing one account.report.line's name from taking up an entire page of the general ledger pdf. This allows many more batched invoices to be shown in the report and a much greater time range of data to be printed without hitting the fd limit. I suggest changing it at the general ledger report level rather than in the account.move.line _compute_display_name function, as we probably still want to see the full display_names at the invoice level. On runbot, the machine has different memory constraints than on sh / local, so it hits the following error before the one above: Wkhtmltopdf failed (error code: -11). Memory limit too low or maximum file number of subprocess reached. Message : Steps to Reproduce on 19.0 newdb: 1. newdb -n test_gl -v 19.0 2. ensure ulimit is set to 1024 in shell that runs odoo instance by running ulimit -n 1024 to mimic ulimit of sh environment 3. run db with python3 odoo-bin, ensuring high enough memory constraints to simulate multi worker sh instance, i.e. --limit-memory-soft=12884901888 --limit-memory-hard=1288490188 4. install sales, accounting, stock 5. install demo data 6. create invoices with 100+ associated sales orders 7. generate the pdf 8. Increase the amount of invoices till the general ledger page count hits ~1010+, where you will hit the error. Notes: opw-ticket-6201508 closes #118067 Forward-Port-Of: odoo/enterprise#118067
2 changes
Resolved issues and error corrections
A recent issue preventing users from adding cover images to Knowledge articles has been resolved. The fix corrects a technical error within the Knowledge module related to how cover uploads were handled, ensuring a smoother user experience. This resolves a crash that occurred during the upload process.
Original PR description
Steps to reproduce: 1. Install Knowledge. 2. Create an article. 3. Open the more actions menu. 4. Click "Add Cover". 5. Upload a cover image. Issue: - The upload crashes with the following traceback: `Uncaught Promise > this.props.setAbortUploadsCallback is not a function` Cause: - `KnowledgeCoverSelector` extends the html_editor `ImageSelector`, whose upload flow registers an abort callback through setAbortUploadsCallback. The generic MediaDialog provides this callback, but KnowledgeCoverDialog renders KnowledgeCoverSelector directly and did not pass it. As a result, the inherited upload flow called a missing prop. Solution: - Pass setAbortUploadsCallback from KnowledgeCoverDialog to KnowledgeCoverSelector and abort pending uploads when the cover dialog is discarded. Alternative approach: - Make ImageSelector tolerate callers that do not provide setAbortUploadsCallback by calling it with optional chaining. opw-6176716
This update fixes an issue where placeholder images were unnecessarily included in menu synchronization, leading to slower loading times. Now, only actual product images are sent, resulting in a more efficient and responsive menu display for users. This change improves the overall user experience.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119883 Forward-Port-Of: odoo/enterprise#119482
2 changes
Resolved issues and error corrections
This update resolves an issue where placeholder images were unnecessarily included in the menu synchronization process. By only sending actual image URLs, we've reduced data transfer and improved the speed and efficiency of menu updates, particularly for products with images. This results in a smoother user experience.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119883 Forward-Port-Of: odoo/enterprise#119482
This update resolves a technical issue where the journal report's multi-country tax grids were incorrectly displaying country names when multiple countries were selected. The fix ensures that all country options are correctly shown, improving the accuracy of financial reporting across various international operations. This update corrects a display error impacting multi-currency reporting.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore. Forward-Port-Of: odoo/enterprise#119348
8 changes
New functionality added to Odoo
This update introduces new invoice types specifically designed for Jordan's export regulations, including 'transit,' 'foreign trade,' and 'free zone transfer.' It ensures these types are only accessible to registered Jordanian taxpayers, aligning with local tax laws and improving compliance. This change supports smoother international trade operations.
Original PR description
Extend l10n_jo_edi_invoice_type with JoFotara scope codes (3-5): transit (3), foreign trade (4), and free zone transfer (5). Validate that scope codes 3-5 are only available to registered taxpayers. task-4769255 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This update resolves an issue where a JSON decoding error could occur when downloading ETA invoice PDFs. A recent change introduced a workaround, but a new error type wasn't being caught. This fix adds a catch block to properly handle the `json.JSONDecodeError`, ensuring stable invoice processing.
Original PR description
When we download the ETA invoice PDF, a JSONDecoderError can happen when calling the json() method on the request. This error is properly caught by Odoo : https://github.com/odoo/odoo/blob/7a9a340e0dbac470c4bea3f8ce8a32e55f3e82e6/addons/l10n_eg_edi_eta/models/account_edi_format.py#L58-L60 However, the following commit introduced a monkeypatch to handle errors when the simplejson library is installed : 2435fe76eec1fc4320ef71726fc7f16ece653a32 If we meet the conditions, the original error is replaced by a json.JSONDecodeError which is not caught during the previous process. We propose to add this error to the catch block. This modification was inspired by the commit d483dac144a9caf84c44b9d8d394ea327ca87cfe. opw-6266862 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where order totals and refund amounts were incorrectly calculated after tax changes or refunds were processed in Point of Sale. The fix ensures historical order prices are preserved, providing accurate totals for both paid orders and refunds. This improves the reliability of financial reporting within the POS system.
Original PR description
Steps to reproduce 1. Create a product at $30 with a 15% tax-excluded tax (total = $34.50) 2. Sell and pay the order 3. Edit the tax and toggle price_include = True 4. Open POS, go to Orders > Paid —…
Steps to reproduce 1. Create a product at $30 with a 15% tax-excluded tax (total = $34.50) 2. Sell and pay the order 3. Edit the tax and toggle price_include = True 4. Open POS, go to Orders > Paid — the order total shows $30 instead of $34.50 5. Click Refund — the refund total also shows $30 instead of $34.50 Issue https://github.com/odoo/odoo/blob/130c5266e0fc37f64f58f67b44c84130643bec20/addons/point_of_sale/static/src/app/store/models.js#L1067-L1090 get_all_prices() recomputes prices from price_unit using current tax objects, ignoring price_subtotal/price_subtotal_incl already serialised in the order JSON. When price_include changes on a tax after an order is paid, the historical total is lost. https://github.com/odoo/odoo/blob/130c5266e0fc37f64f58f67b44c84130643bec20/addons/point_of_sale/static/src/app/store/models.js#L1580-L1608 this.locked was assigned after the orderlines loop, so Orderline.init_from_JSON could not use it to distinguish paid from draft orders. https://github.com/odoo/odoo/blob/130c5266e0fc37f64f58f67b44c84130643bec20/addons/point_of_sale/static/src/app/screens/ticket_screen/ticket_screen.js#L653-L668 _prepareRefundOrderlineOptions passed price_type: "automatic" which triggered a fresh get_all_prices() with current taxes, producing the same wrong total on refunds. Solution Move this.locked assignment before the orderlines loop. When locked, pin price_subtotal/price_subtotal_incl from JSON in Orderline.init_from_JSON and return them early in get_all_prices(), scaling by qty/lineQty so per-unit display calls (get_all_prices(1)) remain correct. Read amount_total/amount_tax from JSON and return them directly in get_total_with_tax()/get_total_tax() for locked orders. Carry price_subtotal/price_subtotal_incl in the refund detail snapshot and inject them (scaled by partial-refund ratio) as extras on the refund orderline. opw-6097256
This update resolves an issue causing blank content in snail mail documents during validation. The problem stemmed from a recent change that incorrectly used a PDF source. This fix ensures the correct PDF is utilized, resulting in properly formatted mail documents.
Original PR description
This commit fixes a regression introduced in odoo/odoo@dc72061383a4 where, while fixing the calls to actually merge page on a pdf writer instead of the reader, the wrong pdf was used as a source.
This update fixes an error in the VAT balance calculation within the l10n_uy module for Uruguay. The previous formula was inaccurate, leading to incorrect reporting. This change ensures accurate VAT reporting, aligning with local tax regulations.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_uy 2. Go to tax report and see the formula of the VAT balance that is incorrect ### Reason to introduce the fix: Correct the formula to display the right amount. opw-6261211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where cron workers weren't efficiently managing database connections. By introducing new configuration variables for cron workers, we can now limit their registry usage, reducing memory consumption and improving overall performance. This ensures Odoo runs smoothly under heavy background workloads.
Original PR description
The configuration option `registry_lru_size` does not exist and does not work at all in recent versions. Defining odoo-specific environment variables to handle: - ODOO_REGISTRY_LRU_SIZE: the default registries size - ODOO_REGISTRY_LRU_SIZE_CRON: overwrite for cron workers Cron workers have often a different workload than HTTP workers and we may set a different limit there. If the limit is lower than the number of databases, a cron job will not reuse registries because it cycles through all known ones - in such cases, we can set a lower limit to keep the memory lower. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a bug that caused a 'divide by zero' error when generating Jordanian e-invoices with invoice lines having a quantity of zero. The fix ensures invoices with zero quantities can now be successfully sent to JoFotara, improving invoice processing reliability. This resolves an issue reported in opw-6262469.
Original PR description
Steps to reproduce: - Ensure Jordanian e-invoicing is installed - Create an invoice where one of the lines has a 0 quantitiy - Send the e-invoice JoFotara (Jordan EDI) Current Behavior: You will get a divide by 0 error popup Expected Behavior: No error and the invoice is sent opw-6262469
Documentation and clarification updates
This update formally includes Djody Kort from Codeforward B.V. in Odoo's contributor legal agreement. This is a standard step for Codeforward contributions and ensures proper licensing compliance. It also prepares for a future bug fix related to server stability.
Original PR description
Adds me (Djody Kort, Codeforward B.V.) to the List of contributors in the existing Codeforward Corporate CLA (`doc/cla/corporate/codeforward.md`, signed by Sander Lienaerts). Prerequisite for an upcoming bug-fix PR to `service/server` — a SIGHUP exit-130 race in `ThreadedServer` under `--dev=reload`. Targeted at 17.0 (the lowest branch the fix applies to) per the CLA signing guide.