Tuesday, May 5, 2026
10 changes · saas-18.3
Resolved issues and error corrections
This update fixes an issue where the system incorrectly reserved stock quantities when using the 'Smallest number of packages' removal strategy. The fix ensures that stock is accurately reserved, preventing over-reservation and ensuring correct inventory management. This improves the reliability of stock tracking.
Original PR description
Issue ----- When there is a packaged quant in stock, the `least package` removal strategy has unexpected behaviour. Steps to reproduce ----- - Enable packages - Create a product AAA tracked by SN -…
Issue ----- When there is a packaged quant in stock, the `least package` removal strategy has unexpected behaviour. Steps to reproduce ----- - Enable packages - Create a product AAA tracked by SN - product category removal strategy set to "Smallest number of packages" - Create a reception for 5 units - Generate serials - Put last line in pack - Confirm reception - Create delivery for 2 units of AAA - Mark as Todo - Change the quants taken: instead of SN 5, take SN 3 (so take SN 3 & 4) - Create a delivery for 3 units of AAA - Mark as Todo > Quantity reserved is one, it only reserved SN 5 Cause ----- The problem arises in `_run_least_packages_removal_strategy_astar`. Because there is an available quant inside a package, we continue past https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L675-L676 We end up at https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L724 The `generate_domain` function has a problem: if there sin't enough products inside packages to satisfy the demand, it searches for items not in packages to take from. https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L701-L705 This search is flawed, because it does not take into account the fact that the quant might already be reserved. So it expands the domain with an `AND` on quant ids that are not available. This leads to `quants` in `_get_reserve_quantity` containing unavailable quants https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L866 This later gets "caught" in `available_quantity` https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L897 and the quants don't get reserved a second time thanks to https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L912-L914 but this also means the reservation is incomplete. Note that calling `action_assign` a second time will correctly reserve the remaining quantities, as there is no package left to reserve in stock, so we do go in https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L675-L676 and avoid the faulty logic. Solution ----- Ideally, we would use the value of `available_quantity` in our search domain. However, the field is not stored https://github.com/odoo/odoo/blob/c359e21457ca3adf5ca713b7aa30e198d0b08f7c/addons/stock/models/stock_quant.py#L88-L91 Our options are: - make the field stored (not stable) - add a search function - filter reserved quants out of `single_item_ids` First option is not stable. Second option requires subqueries to compare `quantity` and `reserved_quantity`. Third option is the least bad one, with only a very situational performance loss. ----- Ticket: opw-5972350 Forward-Port-Of: odoo/odoo#261568 Forward-Port-Of: odoo/odoo#256106
This update fixes a bug preventing website appointment syncs from appearing in Outlook calendars. Previously, a timing issue with the synchronization cron prevented events created through appointments from being properly synced. This change ensures all website appointments are now reliably synchronized with Outlook, improving user scheduling and calendar integration.
Original PR description
Before this change, the "Outlook: synchronization" cron would not create calendar events on Outlook's side in _sync_odoo2microsoft due to a filter for calendar.events written to within 5 minutes of…
Before this change, the "Outlook: synchronization" cron would not create calendar events on Outlook's side in _sync_odoo2microsoft due to a filter for calendar.events written to within 5 minutes of microsoft_last_sync_date, when _sync_data is not called when a calendar.event is created, such as through website.appointment. microsoft_last_sync_date was set to datetime.now() at the beginning of _sync_microsoft_calendar, which would skip a large period of time between the last sync and now, if the only syncs were triggered through cron, and not _sync_data (by opening the calendar app). To reproduce, Default "Outlook: synchronization" is ran every 12 hours. 1) Calendar event is synced through "Outlook: synchronization" cron at 00:00, setting microsoft_last_sync_date to 00:00 2) A website.appointment is created for a resource with Outlook calendar sync enabled any time between 00:01 - 11:54. 3) "Outlook: synchronization" runs again at 12:00, which sets microsoft_last_sync_date to 12:00, and filters out calendar.events based on their write_dates in _extend_microsoft_domain that need syncing outside of 11:55 to 12:00. This change removes setting of microsoft_last_sync_date at the beginning of _sync_microsoft_calendar, where we need to use the old value before setting it at the end of _sync_microsoft_calendar. opw-5212908 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261935 Forward-Port-Of: odoo/odoo#245964
This update resolves a technical issue preventing invoices generated for German XRechnung compliance from being accepted by strict validator systems. The fix removes unnecessary whitespace from the XML attachments, ensuring compatibility with regulatory standards and avoiding invoice rejection.
Original PR description
### Issue: Some strict validators, such as the German XRechnung validator, reject generated documents because the `EmbeddedDocumentBinaryObject` contains leading and trailing whitespace ### Cause:…
### Issue: Some strict validators, such as the German XRechnung validator, reject generated documents because the `EmbeddedDocumentBinaryObject` contains leading and trailing whitespace ### Cause: Before 18.4, `_postprocess_invoice_ubl_xml()` used f-strings to generate the XML content With this formatting, the result of: `base64.b64encode(attachment_values['raw']).decode()` was indented together with the XML block, introducing unwanted whitespace and line breaks inside `EmbeddedDocumentBinaryObject` ### Steps to reproduce: - Install `l10n_de` and switch to the DE Company - In Settings, enable Peppol and Activate Electronic Invoicing - Create and confirm an Invoice (Customer: DE Company, any product line with tax) - Send the invoice via Peppol - Check the generated XML attachment ### Before the fix: The XML contains formatted content such as: ```xml <cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="INV_2026_00005.pdf"> content </cbc:EmbeddedDocumentBinaryObject> ``` This formatting introduces leading/trailing whitespace and may be rejected by strict validators. ### After the fix: The XML is generated without extra whitespace: ```xml <cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="INV_2026_00005.pdf">content</cbc:EmbeddedDocumentBinaryObject> ``` opw-6121616 Forward-Port-Of: odoo/odoo#262472
This update resolves a bug where incorrect industry data (UNSPSC) was being added to new partner tags when creating companies from invoices. The fix ensures that company data is created correctly, aligning with how partner tags are populated from standard autocomplete features. This improves data accuracy and consistency.
Original PR description
Partner Autocomplete was updated so DnB industry data (UNSPSC) is no longer stored on Partner Tags. That behavior was applied to the name/VAT char widget, but creating a company from a Partner…
Partner Autocomplete was updated so DnB industry data (UNSPSC) is no longer stored on Partner Tags. That behavior was applied to the name/VAT char widget, but creating a company from a Partner many2one (e.g. customer/vendor on an invoice) still used the old path: calling an IAP suggestion `iap_partner_autocomplete_add_tags` Steps to reproduce: ------------------- * Open a customer invoice (draft). * On Customer, search a company name and pick a Partner Autocomplete line to create a new company. * Save the quick-create dialog. > Observation: The new contact still had Partner Tags populated from DnB industry data (UNSPSC), unlike contacts created or enriched from the contact form autocomplete. (see video on ticket to avoid using more IAP credits) Why the fix: ------------ Align `res_partner_many2one` with `field_partner_autocomplete`: do not call `iap_partner_autocomplete_add_tags`. From task-5373200, industries from DnB must no longer be added as Partner Tags. opw-5972360 Forward-Port-Of: odoo/odoo#260078
This update resolves an issue where self-billing invoices were incorrectly processed as standard invoices, specifically when generating UBL documents for Peppol. The fix ensures the correct document type ('credit_note') is used, allowing for accurate self-billing invoice creation and compliance. A demo setup has also been added for testing.
Original PR description
To reproduce: - Activate Peppol - Activate selfbilling on your purchase journal - Create a Vendor Refund - Generate the UBL => The InvoiceTypeCode is 389, meaning it's considered a selfbilling invoice, not a selfbilling credit note. The issue is that we never put the document type of credit_note for selfbilling documents as it wasn't expected. invoice was, due to a else encompassing invoices and bills. Also add a handle demo to be able to create selfbilling documents in demo mode. opw-6132226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261872 Forward-Port-Of: odoo/odoo#260941
This update resolves an issue causing incorrect rounding when importing purchase orders processed through OCR. The fix restores the original rounding precision, which was designed for EDI, rather than the OCR process, ensuring accurate financial data. This change improves the reliability of purchase order imports.
Original PR description
Since commit odoo/odoo@86463ce, there could be rounding issues when importing a purchase order matched through the OCR. A first attempt at fixing this was done in commit odoo/odoo@5dbb814, but it was eventually reverted as deemed too risky for a stable branch. More information about how the rounding error occurred is available in that commit description. This second fix should be much safer, we simply don't disable the rounding precision when the OCR is used, as this was intended for EDI in mind in the first place, not the OCR. opw-[6113387](https://www.odoo.com/odoo/my-support-tasks/6113387) Forward-Port-Of: odoo/enterprise#116021
A recent update caused manufacturing orders to incorrectly limit the number of Bill of Materials (BoM) components processed. This fix ensures that all components, regardless of quantity, are accurately reflected in the manufacturing order moves. This resolves a potential issue with incomplete production tracking.
Original PR description
Bug introduced in: https://github.com/odoo/odoo/commit/14d3893c763f6413581e7f36099cee0adb2caa83 Steps to reproduce the bug: - Create a BoM with more than 40 components - Create a manufacturing order with this BoM Problem: Only the first 40 components are taken into account and their moves are created; the remaining ones are not created. opw-6186544 Forward-Port-Of: odoo/odoo#262692
This update resolves an issue where discounts weren't being imported accurately due to rounding discrepancies. The fix adjusts the import process to prevent rounding of discounts, ensuring the subtotal in Odoo matches the original invoice file. This improves data accuracy for Italian VAT invoices.
Original PR description
**PROBLEM** When importing an invoice, we don't want to round the discounts, to avoid discrepancy between the subtotal computed by Odoo, and the subtotal of the file we import. To do this, we change the decimal precision of discount to 100 digits when importing files. However, float_round wasn't built with this in mind, in float round, we add a small epsilon to fix some rounding issue. This small epsilon changes the amount of the discount (50.0 -> 0.5000000000004) and this changes the subtotal. **STEP TO REPRODUCE** 1. Install l10n_edi_it. 2. Change the VAT number of IT Company to 05098540288 (to match the one on the file to import). 3. Import the file present in the bug ticket. 4. Notice the subtotal of the line doesn't match what's in the invoice. **FIX** We skip rounding of the discount on import. Ticket [link](https://www.odoo.com/odoo/project.task/6046324) opw-6046324 Forward-Port-Of: odoo/odoo#262562 Forward-Port-Of: odoo/odoo#256037
This update significantly improves the speed of importing large XML bills, particularly those received via Peppol or manual upload. The changes address a previous performance bottleneck by reducing the number of database queries and streamlining data updates. This results in a much faster upload process, enhancing efficiency for users.
Original PR description
### Description: The upload and import process for large XML bills via Peppol or manual upload was inefficient due to two primary bottlenecks. First, the system performed individual queries per line to match products, taxes, and accounts, leading to an N+1 query issue. Second, multiple write operations were executed on each line to update various fields. This commit introduces batching and improve caching for these operations to reduce database call. ### Benchmark: | N° of lines | Before | After | |-------------|---------|-------| | 30264 | Timeout | 11min | ### Reference: opw-5416612 Forward-Port-Of: odoo/odoo#248680
This update corrects a bug in the POS Employee Login feature. Previously, leaving the 'Basic rights' field empty prevented certain employees from logging in. Now, all employees can log in as basic cashiers when Employee Login is enabled and 'Basic rights' is left blank, aligning with previous Odoo versions.
Original PR description
With Employee Login enabled in POS, leaving the “Basic rights” field empty is meant to allow all employees to log in as basic cashiers. In v19, configuring at least one Advanced/Minimal employee while keeping “Basic rights” empty incorrectly restricted the login list to only the explicitly configured employees (and the linked backend user), so other employees could no longer sign in. Steps to reproduce: ------------------- * Go to POS settings and enable Employee Login. * Add at least one employee in Advanced rights. * Leave Basic rights empty. * Open POS login. > Observation: Only Advanced can sign in. Other employees are missing. Why the fix: ------------ The employee loading domain must only become restrictive when Basic rights is explicitly set. If Basic rights is empty, all company employees should remain selectable, and Advanced/Minimal should only affect roles, not visibility. Align with 19.1 behavior/state of code. opw-6170066