Thursday, June 11, 2026
44 changes · saas-19.1
Resolved issues and error corrections
This update resolves an issue where users could view financial budgets created in other companies. The fix adds a security rule to the budget model, ensuring that users only see budgets associated with companies they are actively connected to. This improves data security and prevents unauthorized access to financial information.
Original PR description
**Steps to reproduce:** - Install the `account_reports` module. - Create a new company. - Navigate to Accounting > Configuration > Financial Budgets. - Create a new budget record. - Switch to another company. - Open the list view of Financial Budgets. **Observation:** The budget record created in another company is still visible. **Root Cause:** The model `account.report.budget` does not have any record rule restricting access based on company. As a result, users can see financial budgets belonging to other companies even if they are not connected to them. **Fix:** This commit allows users to hide financial budgets from companies they are not connected to by adding a record rule on `account.report.budget` opw-6083892 Forward-Port-Of: odoo/enterprise#120059 Forward-Port-Of: odoo/enterprise#114771
This update fixes an issue where the strikethrough price on product configurators wasn't updating correctly when the unit of measure (UOM) was changed. The fix ensures the system accurately reflects the price based on the selected UOM, improving the shopping experience and price accuracy for customers.
Original PR description
Steps to produce: --- - Install `website_sale` module. - Enable ` Units of Measure & Packagings `and `Comparison Price` features from settings. - Create product > set sales price as 5 and Compare to…
Steps to produce: --- - Install `website_sale` module. - Enable ` Units of Measure & Packagings `and `Comparison Price` features from settings. - Create product > set sales price as 5 and Compare to Price as 12. - From the sales tab, under Upsell & Cross-Sell > set Packagings as pack of 6. - Go to the shop page on eCommerce, and add your product via the shop page (this should open the product configurator). - Change the UOM from the radio. Issue: --- - Changing the UOM doesn't change the strikethrough price. Root cause: --- - At [1], The `_get_strikethrough_price` method was not receiving the selected uom parameter, causing it to compute the compare_list_price based on the product's base uom instead of the user-selected uom. Solution: --- - Pass `uom` parameter from `_get_basic_product_information` to `_get_strikethrough_price` - Apply uom conversion to compare_list_price when the selected uom differs from the product's base uom. - Also fix pricelist base price calculation to use the selected uom. - Update the JS logic to refresh the strikethrough price when the uom changes. [1]https://github.com/odoo/odoo/blob/bfcb22256226ae056e934e2f9e498e8cea4d2f63/addons/website_sale/controllers/product_configurator.py#L101-L154 Before: --- <img width="974" height="321" alt="image" src="https://github.com/user-attachments/assets/f360d730-bedf-4898-ba22-c47ea8fa1df7" /> After: --- <img width="977" height="321" alt="image" src="https://github.com/user-attachments/assets/79d66143-959c-4f39-9272-437cb768837e" /> opw-6201754 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263556
This update resolves a bug where multi-country tax grids on the journal report were not displaying correctly, specifically when more than two countries were selected. The fix ensures that the header colspan is accurate and all countries are displayed, improving the report's usability for users managing international transactions.
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#120032 Forward-Port-Of: odoo/enterprise#119348
This update corrects a technical error in how Odoo validates credit card addresses for Stripe payments. The system was previously not correctly handling the ISO 3166-2 standard for state codes, leading to failures with US addresses. This fix ensures compatibility with Stripe's requirements and prepares for upcoming US functionality.
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 the accrual reports (like 'Bill To Receive') that was causing group totals to incorrectly show as zero. The fix ensures that aggregated amounts are calculated accurately, which is essential for accountants to perform period-end financial analysis. This improves the reliability of these key reports.
Original PR description
### Issue before this commit: In accrual reports (e.g., "Bill To Receive", "Billed Not Received", "Invoices To Be Issued", and "Invoices Not Delivered"), when grouping the list view by fields such as…
### Issue before this commit: In accrual reports (e.g., "Bill To Receive", "Billed Not Received", "Invoices To Be Issued", and "Invoices Not Delivered"), when grouping the list view by fields such as Vendor, the group header totals for the "Received", "Billed", and "Amount" columns display 0.00 even if the interanl lines of the group are not 0.00. ### Steps to reproduce the issue: 1. Download Purchase Accounting and Sale Accounting 2. Go to one of this pages: Billed Not Received, Bill To Receive, Invoices To Be Issued, and Invoices Not Delivered 3. Ensure the view is in its default grouping (grouped by Vendor or Customer) 4. Observe the group header rows for the Received (or Delivered), Billed (or Invoiced), and Amount columns. They all display 0.00 5. Expand a group that contains records with values greater than zero 6. Observe that the individual records populate correctly, but the aggregated group header row continues to display 0.00. ### Cause of the issue: The commit ddc1b681656ea8c70f3231cda20b5a58b9ff7dd6 adapted the code to retrieve the new accrual reports but attempted to fetch grouped records using group[0].id as the dictionary key, while the grouped() method actually used the recordset object as the key. This mismatch caused the dictionary lookup to fail, resulting in 0.00 sums. https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/account_accountant/models/analytic_mixin.py#L40-L48 ### Reason to introduce the fix: This fix restores the core analytical utility of the accrual reports, which are crucial for accountants during period-end closings to evaluate totals at a glance. opw-6232273 Forward-Port-Of: odoo/enterprise#118399
This update corrects a bug that incorrectly calculated non-deductible amounts on vendor bills, particularly when using high deductibility percentages. The fix ensures that tax and non-deductible amounts are accurately reflected in journal entries, improving financial reporting accuracy.
Original PR description
### Issue When setting the partial deductibility percentage to 99% on a vendor bill line, the system incorrectly treats it as 100% deductible and completely ignores the non-deductible part…
### Issue When setting the partial deductibility percentage to 99% on a vendor bill line, the system incorrectly treats it as 100% deductible and completely ignores the non-deductible part Additionally, changing the deductibility percentage on a line with taxes does not trigger an update of the non-deductible tax journal items, leaving the private part taxes unchanged ### Cause In the tax recomputation mechanism, `float_compare` was wrongly configured with `precision_rounding=2` instead of `precision_digits=2` when checking the `deductible_amount` field This rounding error caused 99.00 to be evaluated as equal to 100.00, skipping the creation of the non-deductible line Furthermore, `_sync_tax_lines` relies on `get_base_line_tracked_fields` to detect modifications that require a tax recalculation This tracked field list only included price, quantity, and discount. Modifying the deductibility percentage did not trigger any sync, preventing the non-deductible tax lines from adjusting ### Fix To fix the synchronization, `deductible_amount` is added to the tracked fields for invoices This straightforward approach is preferred here for simplicity However, a more restrictive condition may be needed for example only check it on lines with taxes ### Steps to reproduce - Install `account` - Create a Vendor Bill (Price: 1000$, Taxes: 15%, Professional %: 50) - Check the Journal Items tab to see the Private Part line at 500$ debit and Private Part (taxes) line at 75$ debit - Change the Professional % field on the invoice line to 75 Before the fix, the Private Part (taxes) line remains at 75$ debit - Change the Professional % field on the invoice line to 99 Before the fix, the private part lines completely disappear instead of adapting to 1% opw-6245909 Forward-Port-Of: odoo/odoo#267427
This update resolves a visual glitch in the chatter interface where an empty rectangle appeared next to log notes during editing. The issue stemmed from a system that incorrectly remembered the last position, causing problems when scrolling. This fix ensures suggestions are displayed correctly regardless of scrolling.
Original PR description
# How to reproduce - Go into any form view of a model with a chatter (e.g. Quotation) - Add multiple long log notes. You need to be able to scroll enough to not see the last log note - Click edit on…
# How to reproduce - Go into any form view of a model with a chatter (e.g. Quotation) - Add multiple long log notes. You need to be able to scroll enough to not see the last log note - Click edit on the last log note - Scroll down to the bottom # The problem An empty rectangle is displayed next to the log note in edit mode. # Cause The rectangle comes from the NavigableList Component, which is the list that displays suggestions when typing things like "@" or "#" : https://github.com/odoo/odoo/blob/1fd44c3bb11a79d5b6aa72bf7de5a83e6c45be46/addons/mail/static/src/core/common/composer.xml#L137 This components uses the `usePostion()` hook, which purpose is to try to find the most appropriate place to put the element. It will try different postions (e.g. on the left, below, above, etc.) and will pick the most appropriate one. It will then adjust the element's style to position it correctly. It is possible to ask for a preferred position using the options given to the hook. This position will be prioritized over the others if it is suitable. In the case of the NavigableList of the chatter, we give it either 'bottom-fit' or the 'top-fit' positions, wich means it will prefer to be displayed above or below the message : https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/mail/static/src/core/common/composer.js#L449-L459 But in our case, when we scroll back up, the position of the rectangle stays on the left, even though the below space is available. That is because of this commit that introduced a memorization of the last solution : https://github.com/odoo/odoo/commit/b2b8d2dbb8396d86492a3089db9b1b1545c8f13b https://github.com/odoo/odoo/blob/f2434aac74324a65ccd81aa18c7b0e8318e59fde/addons/web/static/src/core/position/position_hook.js#L59-L61 This means that when we scroll down, the bottom positions fails and so the left one is defaulted to. Since the position is memorized, it stays on the left. The issue with this left position is that another commit introduced some logic that made it so if the position is not "top" or "bottom", then we set the element's height to some value : https://github.com/odoo/odoo/commit/702748e2c8e895d372d07f9aeff273282d1b1a99 https://github.com/odoo/odoo/blob/f2434aac74324a65ccd81aa18c7b0e8318e59fde/addons/web/static/src/core/position/utils.js#L120-L124 And setting the height of the NavigableList makes it so it displayed even when there are no suggestions inside, because the hiding mechanism of the suggestion list relies on the fact that when there are no suggestions, the div is empty and has no height, so it is hidden. # Propose solution We introduce a settings in the options that will allow to skip the memorization of the last position. Since the left position will never be set in the options, no height will be defined. opw-6172407 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where created packages weren't displayed within the barcode picking app when putting items into packs. The fix ensures users can clearly see the source and destination packages during the packing process, improving workflow and reducing potential errors. This enhancement directly addresses a user experience concern.
Original PR description
### Steps to reproduce: - Enable `Lots & Serial Numbers` and `Packages` in the settings - Create a product tracked by SN and add SN001 and SN002 to stock - Create and confirm a delivery for 2 units -…
### Steps to reproduce: - Enable `Lots & Serial Numbers` and `Packages` in the settings - Create a product tracked by SN and add SN001 and SN002 to stock - Create and confirm a delivery for 2 units - Open the Barcode app and open the delivery - Scan the product > Scan SN001 - Click `Put in Pack` ### Current behavior: The created package is not displayed anywhere. Clicking Put in Pack again nests the package into another package without any visible indication to the user. ### Cause of the Issue: The GroupedLineComponent cannot display neither the source or destination package: https://github.com/odoo/enterprise/blob/c5bbcaeed513817fdda1f3f42f4c9b2440264174/stock_barcode/static/src/components/grouped_line.xml#L4-L21 However, our case the grouped line contains only a single line and prevents the users from viewing the sublines since the `Show Reserved Lots` is disabled on the operation type and only one lot (with additional demand) was scanned: https://github.com/odoo/enterprise/blob/c5bbcaeed513817fdda1f3f42f4c9b2440264174/stock_barcode/static/src/components/grouped_line.js#L75-L77 https://github.com/odoo/enterprise/blob/c5bbcaeed513817fdda1f3f42f4c9b2440264174/stock_barcode/static/src/components/grouped_line.js#L44-L55 opw-6237834 Forward-Port-Of: odoo/enterprise#119114
A recent update to Odoo caused an error when generating PDF invoices using the ‘Get ETA Invoice PDF’ button. This fix resolves a technical issue related to how Odoo processes data from external requests, ensuring this button continues to function correctly. This change improves the reliability of invoice generation.
Original PR description
Using the “Get ETA Invoice PDF” button located on the form view of invoices can result in a stacktrace error. Since installing requests==2.25.1 with python 3.10, and using: requests.exceptions.JSONDecodeError Will raise the following error: AttributeError: module 'requests.exceptions' has no attribute 'JSONDecodeError' This change fixes the error by using 'JSONDecodeError' from the 'json' package. Related: https://github.com/odoo/odoo/commit/55bddda59b8f9479d515163852fa8cbc718ddbd3 [opw-6275476](https://www.odoo.com/odoo/project/49/tasks/6275476?debug=assets) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268920
This update ensures that purchase order prices correctly retain the precise cost of products, like 0.001235, instead of rounding them to the currency's decimal precision. Previously, this rounding caused inaccuracies in purchase order calculations. This change improves the accuracy of purchase order pricing and aligns behavior with sales order lines.
Original PR description
Commit 07da917f6e331 introduced `min_display_digits` on product price fields, allowing small prices to be stored without forcing the global `Product Price` decimal precision to be increased. For…
Commit 07da917f6e331 introduced `min_display_digits` on product price fields, allowing small prices to be stored without forcing the global `Product Price` decimal precision to be increased. For example, a product can have a cost of `0.001235`. The value is kept on the product because `standard_price` uses `min_display_digits="Product Price"`. However, when this product is added to a purchase order line, the purchase price computation still explicitly rounds the computed unit price using the currency decimals and the `Product Price` decimal precision. This is inconsistent with sales: sale order lines preserve very small unit prices correctly. **Current behavior before PR:** A product with `standard_price = 0.001235` keeps that value on the product form. When adding the product to a purchase order line, the computed `price_unit` is rounded by `purchase.order.line`, so the small price is lost. The same issue can happen with vendor prices: a supplierinfo price with more precision than the currency decimals is rounded before being assigned to the purchase order line. **Desired behavior after PR is merged:** Purchase order lines preserve the computed unit price precision, just like sale order lines already do. A product cost or vendor price such as `0.001235` remains `0.001235` on the purchase order line instead of being rounded to currency/Product Price precision. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267941
This update resolves an issue where the website's main menu would intermittently close due to overlapping updates. By closing the secondary menu before opening the main menu, the system now provides a more reliable and consistent user experience. This prevents unexpected errors and ensures smooth navigation for website visitors.
Original PR description
[FIX] website: close the extra menu before opening site menu Update of the extra menu item is done multiple times (cfr `afterFontsloading`). If the extra menu item and the site menu were already open before an update of the extra menu item, the result is a close of the site menu. This can lead to undeterministic error. To solve the problem, the extra menu dropdown is closed before opening the site menu. runbot-240955 Forward-Port-Of: odoo/odoo#269177 Forward-Port-Of: odoo/odoo#266376
This update fixes an issue where purchase order subtotals were calculated incorrectly when some order lines had a quantity of zero. The fix ensures that subtotals are accurately displayed by storing the filtered order lines for subsequent calculations, preventing errors related to indexing.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/commit/3ac515ab55dd6708e0df283c634e2b99fc4a5561 When order lines with qty=0 are filtered out, `line_index` refers to the filtered list but `order_line[line_index+1]` indexed into the full unfiltered recordset, causing section subtotals to fire at the wrong position with incorrect values. Solution: Pre-store the filtered recordset and use it for the next-element lookup opw-6174429 Forward-Port-Of: odoo/odoo#267924
This update fixes an issue where invoices were incorrectly labeled as 'proforma' when printed. The Print button has been made secondary to emphasize the Send action, aligning with the standard invoicing workflow. This ensures invoices are always displayed correctly and simplifies the process for users.
Original PR description
Revert 3ef2c09 which incorrectly added a proforma label when printing posted invoices that had not yet been sent, proforma invoices have an entire feature in the sales app, so an invoice in invoicing should just be an invoice in all cases. --- The Print button on posted invoices was visually styled as a primary action. Make it secondary so the Send action keeps the main visual emphasis, while Print remains available with the same behavior. task-6269645 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269183 Forward-Port-Of: odoo/odoo#268552
This update resolves an issue where users couldn't save a 'Company Name' entered in the portal's account settings. The fix ensures that a new company record is automatically created when a user enters a company name for the first time, aligning with expected functionality. This improves the user experience and data accuracy within the portal.
Original PR description
### Steps to reproduce: - Download "Website" app - In the portal's "/my/account" address form, enter a "Company Name" - Click "Save" to submit the form - Reload the page and check if the company name…
### Steps to reproduce: - Download "Website" app - In the portal's "/my/account" address form, enter a "Company Name" - Click "Save" to submit the form - Reload the page and check if the company name was saved > Company name isn't updated ### Cause of Issue: `_create_or_update_address()` method was passing the 'parent_name' field directly through the main `partner_sudo.write(address_values)` call. https://github.com/odoo/odoo/blob/391cec39b6048ad4f49015fd67888895dc176ee5/addons/portal/controllers/portal.py#L564-L571 Since `parent_name` is a readonly related field (related to `parent_id.name`), the write operation would fail silently to update it, creating orphaned changelog entries instead of properly updating the parent company entity. ### Fix: Since the update of contact forms in v19.1, we can't just edit the "Company Employer" field without assigning an actual partner (existing or create new). The solution here was to add a case to account for when the portal user is an individual adding a "Company Name" for the first time. opw-6115158
This update corrects a labeling inconsistency in the Odoo purchase module. The 'incoming' button has been updated to 'purchase orders' for improved clarity and user understanding. This change ensures users easily identify the action they're taking when creating purchase orders.
Original PR description
Fix label on incoming purchases smart button. "sales order" -> "purchase orders"
This update ensures that tax information for order items is now correctly transmitted to UrbanPiper when test orders are generated. Previously, test orders lacked this crucial detail, leading to potential issues with order processing. This change resolves a technical issue and improves the reliability of our integration with UrbanPiper.
Original PR description
Commit 1: ======== Before this commit: =================== - Test orders sent to UrbanPiper did not include tax details for order items. After this commit: ================== - Tax details are now included in the order item payload of test orders. Task-6013007 --- Commit 2: ======== Cause: ====== In the `without demo` environment, the discount product does not have any `taxes_id`, causing the test assertion to fail. Fix: ==== Set a tax on the discount product in the test to ensure the same behavior in both `with demo` and `without demo` environments. Error-241138 Forward-Port-Of: odoo/enterprise#119764 Forward-Port-Of: odoo/enterprise#109958
This update fixes a bug that occurred when saving multiple forms in Odoo. Specifically, a change in one form's ID caused a misinterpretation of data, leading to a crash. Now, the system safely ignores `onchange` callbacks if the record ID has changed, ensuring stable form updates.
Original PR description
* Open a new record form (the `onchange` RPC is cached). * Open a second new record form (it uses the cached `onchange` RPC). * Save the record before the `onchange` RPC returns. Before this commit, a race condition caused an error to be raised. When `web_save` is executed, it updates the record configuration with the new `resId` without reloading the view. When the pending `onchange` RPC finally returns, the cache callback misinterprets the data as a `web_read` result instead of an `onchange` result due to the updated ID, triggering a crash. Now, the callback safely does nothing if the resId has changed since the request was sent. runbot-243200 Forward-Port-Of: odoo/odoo#268884
This update enhances the accuracy of partner searches by using exact name matches instead of partial matches, reducing incorrect partner identification. Additionally, the system now utilizes bank account details during UBL imports to further refine partner identification, particularly for Peppol transactions. This ensures more reliable data and improved business processes.
Original PR description
Before this commit: * Partner was searched using contains on the name, which could match unrelated partners with similar names (e.g. 'Global Tech' matching 'Global Technologies Ltd'). After this commit: - Partner retrieval now uses an exact name match to avoid incorrect matches caused by partial name search. - The search limit is set to 1 to ensure a consistent result when multiple partners are found. Technical: - Replaced `ilike` with `=ilike` in the name search domain. task-5485563 Forward-Port-Of: odoo/odoo#268922 Forward-Port-Of: odoo/odoo#250309
This update resolves a technical problem preventing the correct display of the daily report title in POS reports. By adjusting how the report template handles XML, the system now correctly integrates with another report and fixes a previous bug where the title was missing when the module was installed without specific Colombian tax settings.
Original PR description
The daily report template was replacing `//h2[@id='daily_report_title']` entirely, removing the node from the XML source. This caused `pos_hr.single_employee_sales_report` (a primary template that applies its own xpaths against the same patched base) to crash at compile time since its xpaths could no longer find that node. Switch from `position="replace"` to `position="attributes"` + `position="after"`: the h2 stays in the XML source at all times so pos_hr's xpaths always resolve, while the original title is hidden at render time via t-if when CO EDI is enabled and the Colombian content is inserted as a sibling after it. As a side effect, this also fixes a pre-existing bug where installing the module with DIAN disabled would render the daily report with no title at all. opw-6265637 Forward-Port-Of: odoo/enterprise#119003
This update prevents the deletion of Peppol invoices and bills, ensuring a complete audit trail for these transactions. Previously, deleting these documents caused traceability issues. Now, documents are marked as ‘cancelled’ to maintain a historical record, complying with regulatory requirements.
Original PR description
Before this commit, invoices and bills sent via Peppol could be deleted, making traceability difficult. Deletion is now forbidden. Documents are instead kept and marked as cancelled to preserve their history. Task-6107420 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258897
This update fixes a warning related to how Odoo generates PDFs using the PyPDF library. The change ensures the PDF generation process is compatible with recent PyPDF updates, preventing potential errors and maintaining stable PDF output. This resolves a technical issue that could have impacted PDF generation reliability.
Original PR description
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's…
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's architecture updates (specifically PR #3638 [^1] and PR #3669 [^2]), a reader's page is intended to be read-only. Mutating it directly (e.g., using `mergePage` or `compressContentStreams`) before attaching it to a writer can break internal object references and cause `NullObject` errors. This commit resolves the warning by inverting the order of operations to ensure we only mutate writable objects. The fix implements the following flow: 1. Add the unmodified source page directly to the `PdfFileWriter`. 2. Retrieve the newly created, writable output page. 3. Apply `mergePage` and `compressContentStreams` exclusively to the writer's copy of the page. [^1]: https://github.com/py-pdf/pypdf/pull/3638 [^2]: https://github.com/py-pdf/pypdf/pull/3669 Forward-Port-Of: odoo/odoo#268865 Forward-Port-Of: odoo/odoo#267958
This update fixes a warning related to how Odoo handles PDF document merging using the PyPDF library. The change ensures that document modifications are handled correctly, preventing potential errors and maintaining stable PDF generation. This improves the reliability of our document processing workflows.
Original PR description
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's…
In recent versions of PyPDF, modifying a `PageObject` directly from a `PdfFileReader` instance triggers a `PageObject.replace_contents` deprecation warning. As identified in the pypdf library's architecture updates (specifically PR #3638 [^1] and PR #3669 [^2]), a reader's page is intended to be read-only. Mutating it directly (e.g., using `mergePage` or `compressContentStreams`) before attaching it to a writer can break internal object references and cause `NullObject` errors. This commit resolves the warning by inverting the order of operations to ensure we only mutate writable objects. The fix implements the following flow: 1. Add the unmodified source page directly to the `PdfFileWriter`. 2. Retrieve the newly created, writable output page. 3. Apply `mergePage` and `compressContentStreams` exclusively to the writer's copy of the page. [^1]: https://github.com/py-pdf/pypdf/pull/3638 [^2]: https://github.com/py-pdf/pypdf/pull/3669 Forward-Port-Of: odoo/enterprise#119694 Forward-Port-Of: odoo/enterprise#119239
This update resolves an issue where calendar events with multiple attendees displayed inconsistent contact information under the 'Contact Details' section. The fix ensures that only the primary attendee (in 1-on-1 meetings) shows their contact details, improving the event description's clarity and accuracy. This change impacts the user experience when viewing calendar events.
Original PR description
When a calendar event has multiple attendees, `_get_contact_details_description` picks the first non-organizer partner from a set-based recordset to render under "Contact Details" in the event…
When a calendar event has multiple attendees, `_get_contact_details_description` picks the first non-organizer partner from a set-based recordset to render under "Contact Details" in the event description. The recordset is built from `partner_ids_from_attendees`, a set whose iteration order depends on Python's hash seed, so the displayed contact is effectively random and not controllable from the UI. Restrict the "Contact Details" block in `_get_contact_details_description` to events with exactly one non-organizer attendee (1-on-1 meetings). For group meetings the block is omitted entirely, since any single attendee picked from a larger group is arbitrary by construction. Steps to reproduce: 1. Go to Calendar > New 2. Add 3+ attendees (e.g. Alice, Bob, Charlie) 3. Save the event 4. Check the Notes tab in the event form => One random attendee's contact info appears under "Contact Details" Ticket [link](https://www.odoo.com/odoo/project.task/6035192) opw-6035192 Forward-Port-Of: odoo/odoo#258901
This change reverts a recent update that caused guest contact archiving to break email confirmations for related pickings. When guest contacts are archived, the system no longer sends picking confirmation emails, disrupting the order fulfillment process. This reversion ensures that picking confirmation emails are consistently sent.
Original PR description
Archiving guest contacts upon SO validation breaks mail confirmations for related pickings. When a guest contact is archived, the ORM automatically filters it out from any search https://github.com/odoo/odoo/blob/e8a372b71dc91a3e3649e572380f59ee648c5bdc/odoo/orm/fields_relational.py#L673-L677 As a result, the partner is silently dropped from the `partner_ids` Many2Many on the mail composer even though we do write it https://github.com/odoo/odoo/blob/e8a372b71dc91a3e3649e572380f59ee648c5bdc/addons/mail/wizard/mail_compose_message.py#L538-L539 and the picking confirmation email is never sent. A potential fix would have been to disable this filtering at the ORM level but that would have impacted any flow that relies on archived partners being excluded. This reverts commit 3a20ff382d164f05d3d6b66e94318ed80aaa41cc. This reverts commit 64d9ded9637286ef0cfd9e65ba7c60d4f48d6c16. This reverts commit ef10f93b77263836815034e15bae6cddbd38c4f9. opw-6232937
This change addresses an issue where archiving guest contacts during sales order validation prevented picking confirmation emails from being sent. The fix reverts a previous change that filtered archived partners, which would have broken other processes. This ensures that picking confirmations are reliably delivered.
Original PR description
Archiving guest contacts upon SO validation breaks mail confirmations for related pickings. When a guest contact is archived, the ORM automatically filters it out from any search https://github.com/odoo/odoo/blob/e8a372b71dc91a3e3649e572380f59ee648c5bdc/odoo/orm/fields_relational.py#L673-L677 As a result, the partner is silently dropped from the `partner_ids` Many2Many on the mail composer even though we do write it https://github.com/odoo/odoo/blob/e8a372b71dc91a3e3649e572380f59ee648c5bdc/addons/mail/wizard/mail_compose_message.py#L538-L539 and the picking confirmation email is never sent. A potential fix would have been to disable this filtering at the ORM level but that would have impacted any flow that relies on archived partners being excluded. This reverts commit 5616a5bbf78c4a50b412a57609c5ff50b80b854d. opw-6232937
This update resolves an error that occurred when users removed the date field in the Accrued Expense Entry wizard. The fix adds a check to ensure the date field has a value before performing comparisons, preventing a type error. This ensures the feature functions correctly and avoids disruption for users.
Original PR description
Currently, error occurs when user removes date on Accrued Expense Entry wizard. Steps to replicate: - Install `purchase` and `accountant` with demo. - Open any Purchase Order > Click on cog menu >…
Currently, error occurs when user removes date on Accrued Expense Entry wizard.
Steps to replicate:
- Install `purchase` and `accountant` with demo.
- Open any Purchase Order > Click on cog menu > Accrued Expense Entry.
- Remove value from `date` and click else where.
Error:
```
File '/home/odoo/odoo19/community/addons/account/wizard/accrued_orders.py', line 67, in _compute_reversal_date
if not record.reversal_date or record.reversal_date <= record.date:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'datetime.date' and 'bool'
```
Cause:
- As the user removed value from `date`, [here] `record.date` is received as False.
- As a result the comparison `record.reversal_date <= record.date` causes this error to occur.
Solution:
- Added a conditional check for `date` before the date comparison.
[here]: https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/account/wizard/accrued_orders.py#L67
No ID
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#265997
Forward-Port-Of: odoo/odoo#262568This update resolves an issue where the Mail Composer would crash when sending emails with a large number of leads (over 500) selected. The fix prevents a technical error related to data processing, ensuring the Mail Composer remains stable and reliable for users managing large customer lists. This improves the overall user experience.
Original PR description
Steps to reproduce: 1. Install `crm` 2. Create leads more than 500. 3. Select all and try to send email 4. Not close the wizard by "X" Issue: - Traceback occurs: `Uncaught Promise > Unexpected end of JSON input` Cause: - res_ids is not set on the composer when more than 500 records are selected. This is expected, as the compute method `_compute_res_ids()` does not write `res_ids` when the number of `active_ids` exceeds 500 (to avoid storing large payloads on the field). Because of this, the code trying to JSON.parse(res_ids) fails while dismissing the wizard at `onCloseWizardModal` Solution: - Fallback to context.active_ids when res_ids is not available opw-5891862 Forward-Port-Of: odoo/odoo#248406
This update resolves an issue where users without HR access rights were seeing a placeholder image instead of their avatar in the timesheet kanban view. The fix ensures that the correct employee image is displayed, improving the user experience and visual consistency.
Original PR description
Steps to reproduce:
- Install the hr_timesheet module
- Create a user without HR access rights
- Create a timesheet
- Log in with the above user
- Open the kanban view
Issue:
Instead of showing the employee's avatar, a placeholder image
is displayed.
Reason:
The user does not have access to the hr.employee model.
Fix:
In this commit, if the user does not have access to hr.employee,
we fetch the image from the hr.employee.public model.
Task: 4461272
X-original-commit: b3018b1ab4bcdfebd8bb83bad38209b96646da3c
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#269262This update fixes an issue where purchase transactions were incorrectly identified as intra-state, leading to inaccurate reporting. The change separates sales and purchase transactions during computation, ensuring the correct transaction type is assigned for all transactions, including inter-state vendor bills. A migration script has also been added to update existing databases.
Original PR description
Previously, for purchase journals, `l10n_in_state_id` was always computed using the current company `state_id`. However, in `_compute_l10n_in_transaction_type`, the `l10n_in_state_id` was compared with the company `state_id` for both sales and purchases. As a result, all purchase transactions were always computed as intra-state, including inter-state vendor bills. This commit handles sales and purchase transactions separately while computing `l10n_in_transaction_type` to ensure the correct transaction type is assigned. Migration also added to update it in existing dbs. Forward-Port-Of: odoo/enterprise#118297
This update fixes a problem where tax reports for Moroccan companies were incorrectly including entries with zero balances. The fix filters out these unnecessary lines, ensuring the reports accurately reflect actual tax liabilities. This improves the reliability and clarity of the tax reporting process.
Original PR description
When generating the tax report for a Moroccan company, entries with a zero balance were appearing in the report. Steps to reproduce: ------------------- * Create a Moroccan company * Create a bill with a tax to pay * Change the bill date and accounting date to a past date * Make a first payment of the bill, with a date to today * Unreconcile the payment, and make a second payment with a date in the past (the same one as the bill date for example) * Now generate the tax report for the period of today > Observation: The report contains useless entries with a zero balance. Why the fix: ------------ We add `HAVING SUM(account_move_line.balance) != 0` to filter out the line that have a zero balance. opw-5911669 Forward-Port-Of: odoo/enterprise#113956
This update fixes a calculation error in the Spanish VAT reports. Previously, withholding taxes were incorrectly included in the total VAT amount. The fix excludes these taxes, ensuring accurate VAT reporting for Spanish businesses and aligning with accounting regulations. This improves the reliability of financial reports.
Original PR description
Step to reproduce - install `l10n_es_reports` and switch to ES company - create a invoice, add a product, set price = 100 - add two taxes (one should be withholding tax) ex: 21%G and 19%whi - confirm it, total payable is now 100 + 21 - 19 = 102 - open vat Books report for ES, see line for this invoice Observation: - for this invoice, in total vat column, we get 102 value - it should be 100+ 21 i.e 121 as we do not include withholding taxes in total vat Cause: - the query for report used to sum up all the taxes for calculating vat Fix: - excluded tax of type "retencion" in tax summation opw-6082329 Forward-Port-Of: odoo/enterprise#114137
This update optimizes how Odoo checks for gaps in account move sequences, reducing unnecessary database queries. By avoiding redundant checks and caching sequence information, the change improves the speed and efficiency of account move processing. This results in faster transaction handling and a smoother user experience.
Original PR description
Commit odoo/odoo@1789308 introduced a new way to check for sequence gaps in account moves. Forward-ported revisions of this change include this early return to avoid some queries (and the inner method is itself there to prevent some costlier queries). If the move has no name (or the default '/'), there is no sense in checking for gaps anyhow - it has no number at all. In addition, calling `_get_sequence_format_param` instead of `_get_next_sequence_format` avoids queries (since it is obtained from the journal and cached, and not checking the previous move every time) as well. Task-5253768 Forward-Port-Of: odoo/odoo#269239
This update resolves an issue impacting Mexican tax reporting (l10n_mx_edi) by correctly inverting the dependencies on PINT and CEN. This ensures accurate tax calculations and reporting compliance for Odoo Enterprise users operating in Mexico, preventing potential reporting errors.
Original PR description
X-original-commit: 3675550ec7a8ccc0b4646f8e24aa38a3b52cf36c Forward-Port-Of: odoo/enterprise#119980
This update significantly speeds up the /my/tasks portal page, especially when dealing with large numbers of tasks. The changes optimize database queries and data retrieval, resulting in a much faster and more responsive experience for users. This enhancement improves overall portal usability and efficiency.
Original PR description
The /my/tasks portal page suffered from severe performance degradation with large task. Three key optimizations: 1. ORDER BY: Use project_id.id instead of project_id in sort orders to avoid resolving…
The /my/tasks portal page suffered from severe performance degradation with large task. Three key optimizations: 1. ORDER BY: Use project_id.id instead of project_id in sort orders to avoid resolving through project.project._order 2. Capped count: Replace the unconditional search_count with a capped version (limit=10k pages). Only fetch the full count when the user navigates beyond page 10,000. 3. Milestone check: Use search(limit=1, order='id') to leverage index-only scans. Benchmark (page 1 load): _prepare_tasks_values (milestone + count, excludes lazy main search): | # Tasks | # Projects | Before PR | After PR | |-----------|------------|-----------|----------| | 500,000 | 2,000 | 0.294s | 0.230s | | 1,500,000 | 2,000 | 0.511s | 0.222s | | 3,000,000 | 12,000 | 1.129s | 0.258s | | 6,000,000 | 24,000 | 2.388s | 0.261s | | *6,000,000| 24,000 | 2.015s | 1.976s | *6M measured while navigating last page (full count triggered). Main search query (ORDER BY fix): | # Tasks | # Projects | Before PR | After PR | |-----------|------------|-----------|----------| | 500,000 | 2,000 | 0.525s | 0.013s | | 1,500,000 | 2,000 | 0.685s | 0.017s | | 3,000,000 | 12,000 | 1.479s | 0.040s | | 6,000,000 | 24,000 | 3.121s | 0.043s | | *6,000,000| 24,000 | 7.562s | 3.781s | Planer before: https://explain.dalibo.com/plan/aa47635ecddadfh5 Planer after: https://explain.dalibo.com/plan/d89gg3f5e8ed529b *6M measured while navigating last page (high offset). - opw-5478903
This update streamlines the process of loading contract templates by simplifying a key component. Previously, the loading process involved unnecessary database calls, which has now been resolved. This change improves performance and efficiency.
Original PR description
It was found that the Load Contract Template button was doing database calls with no domain. This was due to it extending Selection Field, seeing that it doesn't use anything from SelectionField except the props, we've decided to make it a simple Component. task-6259618
This update resolves an issue where purchase order confirmations would fail when a delivery type didn't associate with a warehouse. The fix ensures that the system correctly identifies the default destination location when a warehouse isn't specified, preventing a type error and allowing purchase orders to be processed smoothly.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/commit/e2efdf75f67e631ed7622bb01c127120e639f6c5 Steps to reproduce: Clear the Warehouse field (set it to False) Create a purchase order Set "Deliver…
Bug introduced in: https://github.com/odoo/odoo/commit/e2efdf75f67e631ed7622bb01c127120e639f6c5
Steps to reproduce: Clear the Warehouse field (set it to False) Create a
purchase order Set "Deliver To" to the operation type with no warehouse
Add any product Confirm the PO → TypeError is raised
Steps to reproduce the bug:
- Have at least 2 warehouses
- Go to Inventory > Configuration > Operation Types > Receipts
- Clear the Warehouse field (set it to False)
- Create a purchase order:
- Set "Deliver To" to the operation type with no warehouse
- Add any product
- Try to confirm the PO
Problem:
A traceback is triggered:
``` return self.parent_path.startswith(other_location.parent_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: startswith first arg must be str or a tuple of str, not bool
```
`_get_final_location_record` computes `wh_stock_loc` from
`picking_type_id.warehouse_id.lot_stock_id`. When `warehouse_id`
is False (a valid configuration, operation types can be detached from
any warehouse), `lot_stock_id` short-circuits to False
Solution:
guard the _child_of call with not wh_stock_loc. When the
picking type has no warehouse, wh_stock_loc is falsy and there is
nothing to compare against, so the method falls back to
default_location_dest_id (the only destination available).
opw-6253817
Forward-Port-Of: odoo/odoo#268317This update optimizes how the system checks access rights when opening the reconciliation widget, particularly for large amounts of transactions. Previously, the process was slow due to individual checks being performed, leading to delays. This change improves the speed and responsiveness of the reconciliation feature.
Original PR description
When assigning a value in batch, the ORM doesn't manage to batch the call to `check_access` done in `write_batch`/`write_real` because each write is done individually when setting a value in the compute function. This field is especially annoying because it is read when opening the reconciliation widget on several lines. Forward-Port-Of: odoo/odoo#269063
This update corrects an issue where sequence names generated with time placeholders (like hour and minute) were consistently displaying as '00:00:00'. The change ensures that the time component of the sequence date is correctly included, resolving a discrepancy in generated order names. This improves data accuracy and consistency.
Original PR description
## Issue When using a prefix containing a time-based placeholder (`%(h24)s`, `%(h12)s`, `%(min)s`, `%(sec)s`) with *Subsequences per date\_range*, the time information are missing and consistently…
## Issue
When using a prefix containing a time-based placeholder (`%(h24)s`, `%(h12)s`, `%(min)s`, `%(sec)s`) with *Subsequences per date\_range*, the time information are missing and consistently set to 0 when interpolating the prefix.
## Steps to reproduce
1. Install *Sales* (`sale_management`)
2. In Settings > Technical > Sequences, update the `sale.order` sequence:
- Prefix: `S/%(y)s/%(month)s/`
- Suffix: `/%(h24)s/%(min)s/%(sec)s`
- Tick the *Use subsequences per date_range* checkbox and set a range for the current month
3. Create and confirm a SO
4. **The name of the SO correctly contains the Quotation date in the prefix, but the suffix is set to /00/00/00, even though the quotation date contains time information.**
## Cause
Commit https://github.com/odoo/odoo/commit/f7c330d83cc3 sets the `ir_sequence_date` to a `datetime.date` object in `IrSequence._next`. This leads to the time information missing from the interpolation dict:
https://github.com/odoo/odoo/blob/d58f4ed332af35f6de26a93f07adf05368731e20/odoo/addons/base/models/ir_sequence.py#L211-L214
## Fix
The context key `ir_sequence_date` should be set to a `datetime.datetime` object to correctly interpolate the time information in the prefix/suffix of a sequence. To do so, the `tzinfo` needs to be drop for the date to be interpretable by the `fields.Datetime.from_string` method:
https://github.com/odoo/odoo/blob/d58f4ed332af35f6de26a93f07adf05368731e20/odoo/orm/fields_temporal.py#L239-L244
The time is not cast to a specific timezone (e.g., UTC) before dropping the tzinfo, as doing so would lead to incoherent time information from the user's perspective. For example, creating a SO at 13:00 in Brussels (UTC+2) would result in `11` being used as the hour to interpolate the `%(h24)s` placeholder.
opw-6104485
Forward-Port-Of: odoo/odoo#260782A recent update inadvertently removed the duplicate and delete buttons from the page properties dialog in the website settings. This change was caused by a renaming of a configuration property. This update restores the functionality, ensuring users can properly manage their static website pages.
Original PR description
Steps to reproduce: 1. Go to Website. 3. Open the page properties dialog of any static page. Issue: The duplicate and delete page buttons are missing from the page properties dialog, although they were available until version 19.0. Cause: After the changes introduced in [1](https://github.com/odoo/odoo/pull/220325/changes), the `buttonTemplate` prop was renamed to `buttonDialogTemplate`. However, this new prop was not handled in the page properties dialog, causing the buttons to disappear. task-6171493
This update resolves an issue where users couldn't properly set prices for hybrid subscription products. Now, the system requires a plan to be selected for subscription products and correctly filters pricelist items to allow one-time sales when a plan is chosen. This ensures accurate and flexible pricing for all subscription types.
Original PR description
Before this commit:
1. Users could save a pricelist rule for a pure subscription product without assigning a plan.
2. Hybrid subscription products (where 'Allow One-Time Sale' is True) were filtered out of the pricelist item form when no plan was selected, preventing users from setting a one-time price.
After this commit:
- The `plan_id` field on the product template form is now mandatory if the product is a subscription and does not allow one-time sales.
- The `product_tmpl_id` domain on the pricelist item form is updated to `['|', ('recurring_invoice', '=', bool(plan_id)), ('allow_one_time_sale', '=', True)]`, allowing users to select hybrid products for one-time pricing.
task: 6164232This update corrects a bug where the Timesheet Assistant was incorrectly matching tasks and projects with disabled timesheets. The fix ensures the assistant only considers active timesheets, improving the accuracy of time tracking and reporting. This prevents wasted effort and ensures data integrity.
Original PR description
Currently, the Timesheet Assistant (ActivityWatch) can match events to projects or tasks that have timesheets disabled, either via Custom Rules or Historical Memory.
This commit resolves the issue across the entire pipeline:
- Backend: Updated `resolve_assistant_models_targets` to efficiently filter out records where `allow_timesheets` is False using a search domain.
- Frontend: Updated the `loadData` JS pipeline to intercept and wipe any project/task IDs rejected by the backend, ensuring they cleanly fall back into a single "Unmatched" group.
- Views: Added the `[('allow_timesheets', '=', True)]` domain to `project_id` and `task_id` fields in `aw.rule` views to prevent users from creating invalid rules.
Task: 6267401This update resolves an issue where the EC List XML reports generated for Belgium (l10n_be) incorrectly treated invoices with the same VAT number as separate entities. This resulted in rejection by the tax agency. The fix ensures that invoices with identical VATs are grouped together in the XML export, meeting tax agency requirements.
Original PR description
With l10n_be: - Create two contacts with the same VAT - Create an invoice for each that is EC List compatible - Generate the return and export the EC List XML In the generated xml the two partners with the same vat are treated as different partners, which causes a rejection by the tax agency. opw-6109585 Forward-Port-Of: odoo/enterprise#117702
This update corrects an assertion error related to product naming within the intercompany sales and purchase rules. The issue stemmed from a recent addition of product attributes, which caused inconsistencies in product names across different Odoo apps. This fix ensures consistent product naming during intercompany transactions.
Original PR description
**Step to reproduce** Reproducible in single app The "name" field make this assertion fails: ``` self.assertRecordValues(sale_order.order_line[0], [{ "product_id":…
**Step to reproduce**
Reproducible in single app
The "name" field make this assertion fails:
```
self.assertRecordValues(sale_order.order_line[0], [{
"product_id": no_variant_product_tmpl.product_variant_id.id,
"name": 'No Variant\nAttribute: Value 1',
```
**Observation**
The name will not be the same depending which app are installed, purchase_product_matrix, changes the name of the product if there is a attribute value of a never variant: https://github.com/odoo/odoo/blob/f399f99d4e0e562d25e1de32336e8d6a55199b9b/addons/purchase_product_matrix/models/purchase.py#L168-L174 Which will be passed to the purchase_order_line:
https://github.com/odoo/odoo/blob/f399f99d4e0e562d25e1de32336e8d6a55199b9b/addons/purchase/models/purchase_order_line.py#L630-L634 that will pass the information to the sale order:
https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/sale_purchase_inter_company_rules/models/purchase_order.py#L114 https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/sale_purchase_inter_company_rules/models/purchase_order.py#L125-L126
**Additional information**
Since this [commit](https://github.com/odoo/odoo/commit/b8ebb26553f8170061debc7532606fd4777f0fcd#diff-5684edced9bdfc98021a85de4c6cdf691ea7add74e56ab50334a1d7db9ef4224R90) product_no_variant_attribute_value_ids was directly added in the purchase module.
breaking commit : https://github.com/odoo/enterprise/commit/bf286a0005b8e22ffa717419cd2dfacff861a265
runbot-242362
Forward-Port-Of: odoo/odoo#268016This update resolves an issue where extraneous code was carried over during a recent update to the Odoo Enterprise platform. The fix ensures the reporting functionality for Peru (l10n_pe_reports) operates efficiently and without unnecessary overhead. This improves the overall stability and performance of the system.
Original PR description
During the FW port of https://github.com/odoo/enterprise/pull/117891 We forgot to remove the unnecessary code opw-5978673 Forward-Port-Of: odoo/enterprise#120183