Tuesday, May 26, 2026
24 changes · saas-19.1
Resolved issues and error corrections
This update optimizes a key database query used in Point of Sale reporting, resulting in a significant speed improvement. By adding the journal to the search criteria, the system now efficiently utilizes an existing database index, dramatically reducing the time it takes to retrieve necessary data. This translates to faster reporting and a better user experience.
Original PR description
Currently the query to get the closing difference account move is done by searching for the reference of the move, which is not very efficient. This commit optimizes this query by adding the journal…
Currently the query to get the closing difference account move is done by searching for the reference of the move, which is not very efficient. This commit optimizes this query by adding the journal to the search criteria, which allows us to benefit from the index on the journal_id field. Here is an example of the before after on a database with 39 million account_move records. Meanwhile only 10-20K account_move are linked to specific journals used in POS payment methods. All measures are performed with a warmed up cache [Explain Before](https://explain.dalibo.com/plan/h8edf56c09d7dfd7) ### Benchmark: <table> <thead> <tr> <th># of am</th> <th>Before</th> <th>After</th> </tr> </thead> <tbody> <tr> <td>38982635</td> <td>~17s</td> <td>~22ms</td> </tr> </tbody> </table> [Explain After](https://explain.dalibo.com/plan/be2397f176a6b29d) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262148
This update resolves a bug in the HTML Editor that caused a crash when a user removed a table while resizing. The fix restricts resizing to the primary mouse button and prevents the editor from attempting to resize when there's no table to resize, improving stability and user experience.
Original PR description
#### Description of the issue this PR addresses: - Table resize listeners are not cleaned when the table is removed while resizing - Next mousemove runs resize logic with a null target and throws traceback #### Desired behavior after PR is merged: - Restrict resize start to primary mouse button only - Prevent resize logic execution on null targets #### Steps to reproduce: - Open the todo app - Insert a table and select whole table - Move cursor on a table cell border to see resize cursor - Right click and choose Cut from browser context menu - Move the mouse again - Resize logic crashes with null target traceback task-6212279 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264065
This update corrects a migration issue that occurred when certain tax IDs were missing for Maltese companies. The fix prevents a crash caused by attempting to combine a recordset with a missing tax record, ensuring the migration process completes successfully. This improves the reliability of tax data updates for Odoo users in Malta.
Original PR description
### Issue: During migration of Malta taxes, the script can fail when certain tax XML IDs are missing for a company. If the XML ID does not exist, `env.ref(..., raise_if_not_found=False)` returns…
### Issue:
During migration of Malta taxes, the script can fail when certain tax XML IDs are missing for a company. If the XML ID does not exist, `env.ref(..., raise_if_not_found=False)` returns None. Trying to combine a recordset with None causes the migration to fail. Due to recent [commit]
### Traceback:
```py
tax_7 |= env.ref(f'account.{company.id}_VAT_S_IN_MT_7_G', raise_if_not_found=False)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 6589, in __or__
return self.union(other)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 6603, in union
raise TypeError(f"unsupported operand types in: {self} | {arg!r}")
TypeError: unsupported operand types in: account.tax() | None
```
###
Solution:
Use a guard check with the walrus operator (:=) to assign and validate the tax record before union.
This ensures that only existing tax records are added to the recordset, preventing the crash.
Ticket [link1](https://www.odoo.com/odoo/project.task/6159300) [link2](https://www.odoo.com/odoo/project.task/6149387)
opw-6159300
opw-6149387
Forward-Port-Of: odoo/odoo#264327This update corrects an issue where delivery quantities weren't updating correctly after creating multiple production orders (MOs) using a multi-step route with batch sizes. The fix ensures that all MOs created during this process are properly linked to the delivery, guaranteeing accurate inventory updates upon validation. This resolves a discrepancy in how move destination IDs are handled during MO splitting.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-steps routes - Inventory > Configuration > Warehouse Management > Routes - Unarchive MTO - Create a storable product P with a bom using the MTO…
### Steps to reproduce: - In the settings enable: Multi-steps routes - Inventory > Configuration > Warehouse Management > Routes - Unarchive MTO - Create a storable product P with a bom using the MTO Route - In the Miscellaneous tab of the bom tick Batch Size and set it to 2 - Create and confirm a sale order for 6 units of P #### > Three MO's are created but only the last one will update the quantities of the delivery at validation of the production. ### Cause of the issue: The `move_dest_ids` of the `move_finished_ids` is only set on the last of the three productions. That is only the last MO is properly chained to the delivery via an MTO chain. This happens because the `move_dest_ids` field of the `mrp.production` model is a `One2Many` field: https://github.com/odoo/odoo/blob/a2f072fe99a03aaf521bba1965e7f29a1c99e325/addons/mrp/models/mrp_production.py#L223-L224 Which implies that each move can be linked to at most one mrp.production via the `created_production_id` field. However, if you have set a batch size on your bom, it is expected for a single move to create multiple mo's. While the `move_dest_ids` of each of these MO is appropriately set in the create vals to be the mto `stock.move` of the delivery, due to the nature of the `created_production_id` field only the *last* mo will created with a set `move_dest_ids` as this is the only record that will be set as `created_production_id`. However, after the creation of these MO's, the related `move_finished_ids` will be recomputed: https://github.com/odoo/odoo/blob/a2f072fe99a03aaf521bba1965e7f29a1c99e325/addons/mrp/models/mrp_production.py#L1089-L1093 However, the `move_dest_ids` of the created moves will be set to be either the `move_dest_ids` of their production (which is unset for all but the last one) or these of the first production of the same `production_group` that is these generated by a common production split: https://github.com/odoo/odoo/blob/a2f072fe99a03aaf521bba1965e7f29a1c99e325/addons/mrp/models/mrp_production.py#L1263-L1267 Now, since neither are set in our use case, the `move_dest_ids` will not be set on the `move_finished_ids` which implies in particular that the mto link between our productions (but the last one) and the delivery is lost. Fix: Since we can not change the nature of the `move_dest_ids` and `created_production_id` in stable to become Many2Many fields, we need to find a way to propagate the `move_dest_ids` on moves without relying on the probably inaccurate value provided by the production. And, since the compute of the `move_finished_ids` could be launched at many other points than during a create process (because of the many dependencies), we can not solely rely on the creation context but rather new to provide a way to recreate the link from relations at any given point. We therefore rely on the `stock.reference`'s similar to what was done prior to 19.0 via the `procurement_group_ids`: https://github.com/odoo/odoo/blob/132f042ca14012877f608783b57a0ca9c4e565f3/addons/mrp/models/mrp_production.py#L1198-L1202 opw-6188069 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264951
This update fixes an issue where the picking origin document incorrectly referenced the previous MO name after a manufacturing operation type was changed before confirmation. The fix ensures that the picking origin now accurately reflects the updated MO name, preventing data discrepancies in inventory management. This improves the reliability of stock movements.
Original PR description
**Issue**: When the name of a MO changes before confirmation, the picking origin may remain incorrect after confirmation. **Steps to reproduce**: - Make sure that multi-step route is enabled in the…
**Issue**: When the name of a MO changes before confirmation, the picking origin may remain incorrect after confirmation. **Steps to reproduce**: - Make sure that multi-step route is enabled in the settings - Configure the manufacturing route as 2-step - Go to Inventory > Configuration > Warehouse Management > Operations Types - Clone the "Manufacturing" operation type and assign a different Sequence Prefix - Create and save a MO, without confirming it - Change and save the operation type to the cloned one (the MO name changes) - Confirm the MO -> The picking source document uses the previous MO name instead of the new one **Cause**: The source document of the picking (`origin`) comes from its move: https://github.com/odoo/odoo/blob/95c73aa4dd7433f394799fdaaad57a84d750ec5a/addons/stock/models/stock_move.py#L1526 The move origin comes from the procurement values: https://github.com/odoo/odoo/blob/95c73aa4dd7433f394799fdaaad57a84d750ec5a/addons/stock/models/stock_move.py#L1575C13-L1575C56 Which relies on `self.reference_ids[0].name`: https://github.com/odoo/odoo/blob/95c73aa4dd7433f394799fdaaad57a84d750ec5a/addons/stock/models/stock_move.py#L1639 which is never updated, causing the origin to keep the previous MO name. opw-5979778 Forward-Port-Of: odoo/odoo#255874
This update fixes an issue where replenishment order quantities weren't being rounded correctly when using the same unit of measure as the product. Previously, orders would sometimes request an incorrect quantity. Now, replenishment quantities will always be rounded to the nearest whole unit, ensuring accurate stock levels and order fulfillment.
Original PR description
**Issue** Replenishment quantity is not rounded when the replenishment UoM is the same as the product UoM. **Steps to reproduce**: - Enable "Units of Measure & Packagings" setting - Create a tracked…
**Issue** Replenishment quantity is not rounded when the replenishment UoM is the same as the product UoM. **Steps to reproduce**: - Enable "Units of Measure & Packagings" setting - Create a tracked product and add a vendor using the same uom (ex: Unit) - Create a replenishment order rule: - min = 0 - max = 10 - multiple: Unit - Create a sale order for that product with 1.11 units -> It tries to replenish 11.11 units instead of 12 **Cause**: While computing `qty_to_order`, it rounds using the given multiple via `_get_multiple_rounded_qty`: https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/stock/models/stock_orderpoint.py#L471-L475 However, `_get_multiple_rounded_qty` skips rounding when the replenishment UoM matches the product UoM: https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/stock/models/stock_orderpoint.py#L802-L809 opw-[6015189](https://www.odoo.com/web#id=6015189&view_type=form&model=project.task) Forward-Port-Of: odoo/odoo#256006
This update resolves a bug where the Gantt view incorrectly displayed working hours for flexible employees during public holidays. The fix converts all time zone calculations to UTC, ensuring accurate representation of unavailable time slots. This prevents employees from being incorrectly scheduled to work during holiday periods.
Original PR description
[FIX] hr_attendance_gantt: fix gantt view with public holidays Bug reproduction: 1 - Select flex schedule employee (or change its schedule to 40h flex one) and make its contract before 01/01/2026 2 -…
[FIX] hr_attendance_gantt: fix gantt view with public holidays
Bug reproduction:
1 - Select flex schedule employee (or change its schedule to 40h flex one) and make its contract before 01/01/2026
2 - Create a new public holiday on 01/01/2026 (from 00.00 to 23.59 or 23.55 (depends on version, it does not matter))
3 - in attendance app the cell from 00.00 to 01.00 seems white for that day and for selected employee (this cell seems like not holiday and employee can work)
Bug cause:
1 - After a long traceback, _gantt_unavailability in hr_attendance_gantt/HrAttendance, if an employee is flexible then unavailable_intervals is calculated with the Brussel time zone
2 - All other unavailable intervals are converted to the UTC in the function of _gantt_unavailability except in the final lines of the function.
3 - When the employee is flexible and since the conversion is not done in the final lines, it remains 1 hour more (UTC+1), it is from 1 am to 1 am of next day instead of 0 am to 23.59.
Bug solution:
1 - I converted the timezone to UTC to solve the problem.
task - 6067070
Forward-Port-Of: odoo/enterprise#112493This update resolves an issue preventing users from correctly unreconciling SePA CT batch payments with a 'pending' online status. Previously, the system blocked this process, causing delays in bank statement reconciliation. The fix allows the internal unreconciliation flow to bypass validation, enabling accurate bank statement matching.
Original PR description
**Issue:** The account_online_payment module overrides `action_draft` to raise a UserError for sepa_ct payments belonging to a batch with a `payment_online_status` = 'pending' or 'accepted'. This…
**Issue:** The account_online_payment module overrides `action_draft` to raise a UserError for sepa_ct payments belonging to a batch with a `payment_online_status` = 'pending' or 'accepted'. This blocks the bank statement unreconciliation process. When `delete_reconciled_line` is called, it tries to set payments to draft and re-post them, despite it being an internal process not a manual user modification. **Steps to reproduce:** - Setup a 'sepa_ct' payment method on a bank journal. - Create a bill with a vendor with a trusted bank account. - Create a payment for that bill with a 'sepa_ct' payment method. - Add the payment to a batch. - Manually set the `payment_online_status` = 'pending'. - Create a bank transaction and reconcile it with the batch. - Try to unreconcile the lines on the transaction - Result: UserError 'You cannot modify a payment that has already been sent to the bank.' **Fix:** Pass a context flag to `action_draft` during the unreconciliation flow so that the validation is skipped when the call originates from the internal unreconcile flow. OPW-6080464 Forward-Port-Of: odoo/enterprise#117921
This update fixes an issue where Italian electronic vendor bills weren't correctly applying pension fund taxes (Cassa Previdenziale) during import. The change ensures that the system accurately processes invoices generated by third-party software, regardless of the presence of optional XML tags, guaranteeing correct tax calculations for Italian businesses.
Original PR description
### Issue before this commit: When importing an Italian electronic vendor bill using the AssoSoftware standard, pension fund taxes (Cassa Previdenziale) are not applied to the invoice lines. ###…
### Issue before this commit: When importing an Italian electronic vendor bill using the AssoSoftware standard, pension fund taxes (Cassa Previdenziale) are not applied to the invoice lines. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_witholding 2. Change VAT number of IT company with the one in the xml 3. Go to Taxes > 4%F.Pens. > Advanced Options and change Pension Fund Type with TC02 4. Import xml of the ticket in vendor bills 5. P.Fund tax is not assigned ### Cause of the issue: The issue is caused by the following line: https://github.com/odoo/odoo/blob/669b9b84f4d5c8765dc4b451d5da6a95dbb9ded8/addons/l10n_it_edi_withholding/models/account_move.py#L247 Currently, the parser strictly expects the optional <RiferimentoTesto> tag alongside <TipoDato>AswCassPre</TipoDato>. However, several third-party software providers generate valid XML files containing only the AswCassPre block without any optional child tags. ### Reason to introduce the fix: Ensure that the pension fund tax mapped to the line's VAT rate is correctly applied whenever the AswCassPre data type is present, even if the optional reference tags are omitted. opw-6189225 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265914 Forward-Port-Of: odoo/odoo#264083
This update resolves a problem where invoices with year-range invoice numbers (e.g., INV/2025-2026/00001) were failing to send to MyInvois. The fix corrects a technical error in how the system processes these invoice numbers, ensuring accurate transmission of invoices.
Original PR description
Currently, an error is produced when sending invoices to MyInvois if the invoice number uses a year-range sequence. **Steps to Reproduce:(v-19.0)** 1. Install the `accountant` and `l10n_my_edi`…
Currently, an error is produced when sending invoices to MyInvois if the invoice number uses a year-range sequence. **Steps to Reproduce:(v-19.0)** 1. Install the `accountant` and `l10n_my_edi` modules (with demo data). 2. Switch to "MY Company"(Malaysian company). 3. Enable "_Quick Encoding_" for Customer Invoices in Settings. 4. Create a customer invoice with customer "_MY Company_", set a Malaysian classification code and taxes on the invoice line, and confirm the invoice. 5. Set the invoice back to Draft and modify the invoice number with a year-range sequence (e.g., INV/2025-2026/00001), then confirm it again. 6. Open the invoice list view and click **"Send to MyInvois"**. **Error:** `ValueError: not enough values to unpack (expected 4, got 2)` The `_get_sequence_date_range()` method on `myinvois.document` overrides the method from `sequence.mixin` and returns only two values from `date_utils.get_fiscal_year()`. However, it expects the method to return four values at [1]. [1] - https://github.com/odoo/odoo/blob/57b6b8d63b038ede32dfcc833c30e93d0cf4166c/addons/account/models/sequence_mixin.py#L146 Ref: https://github.com/odoo/odoo/blob/1ce06257f877711bd5de5487364909d72b476318/addons/account/models/account_move.py#L4263 sentry-7320998540 Forward-Port-Of: odoo/odoo#266221 Forward-Port-Of: odoo/odoo#253237
This update resolves an error occurring when generating invoices with agricultural tax (ClaveRegimenIvaOpTrascendencia) using the TicketBAI system. The issue stemmed from an incorrect value being submitted, preventing proper invoice processing. This fix ensures accurate invoice generation for clients utilizing this tax regime.
Original PR description
…hase bills **STEP TO REPRODUCE** 1. Create a bill with a invoice line with a regimen agricultura tax. 2. send the bill using TicketBAI. 3. You will get the following error: Error:cvc-enumeration-valid: Value '19' is not facet-valid with respect to enumeration '[01, 02, 03, 04, 05, 06, 07, 08, 09, 12, 13]'. It must be a value from the enumeration. opw-6200686 Forward-Port-Of: odoo/odoo#265785 Forward-Port-Of: odoo/odoo#264037
This update fixes an issue where the search dropdown on the /shop page was partially hidden behind snippet blocks. The change ensures the full search results are always visible, improving the user experience when browsing products. The fix was implemented using JavaScript to adjust the layout of the search bar.
Original PR description
On /shop, when a snippet block sits above the searchbar, the search dropdown was rendered partially hidden behind that block (cropped/unreadable items). Steps to reproduce: =================== 1. Go…
On /shop, when a snippet block sits above the searchbar, the search dropdown was rendered partially hidden behind that block (cropped/unreadable items). Steps to reproduce: =================== 1. Go to /shop. 2. Add a snippet block above the searchbar. 3. Type in the searchbar. => Observed: search results appear cropped, with upper items hidden behind the snippet block above. Root cause: =========== the products grid column (`#products_grid`) has `overflow: auto`, https://github.com/odoo/odoo/blob/d9bb1c1dc90f97b63b87ad762fc4ab36abf7e05f/addons/website_sale/static/src/scss/website_sale.scss#L442 which clips any absolutely-positioned descendant that extends past its bounds. The dropdown's containing block is the searchbar `<form>` (position: relative), which lives inside that column. When the dropdown grew (or flipped to dropup) and extended outside the column, the part outside was clipped, and any positioned snippet siblings above the column painted over the clipped area. Fix: ====== while the dropdown is mounted, lift the `overflow: auto` on its ancestor `div.col` so the menu can extend past the column and paint on top of other content. Done from JS so no SCSS rule has to target the searchbar-specific column. opw-6216317 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265982 Forward-Port-Of: odoo/odoo#265558
This update fixes an issue where automatic check-out was incorrectly calculating extra hours when employees used time off. The change ensures that employee schedules, including time off and breaks, are accurately reflected during automatic check-out, preventing overpayment for hours worked. This improves the accuracy of time tracking and payroll.
Original PR description
# Steps to reproduce 1. Set the Working schedule 40h/week 2. Employee takes 2 hours off from 15:00 to 17:00 and enable automatic check-out 3. Odoo will automatically checks out at 17:06 (scheduled end + tolerance) # Issue - This leads to 2h06 of extra hours being incorrectly recorded. # Fix - Use employee._get_expected_attendances instead, so contract-aware calendar resolution, leaves, and break time handling stay centralized in HR. task-5052044 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235442
This update resolves an issue where certain accounts (119/129) were causing imbalances in the French accounting reports. This change reverts a previous update that introduced the problem, ensuring accurate financial reporting. The fix was triggered by reported errors and is a necessary step to maintain the integrity of our accounting data.
Original PR description
This reverts commit f3851a221dc27d280ce826433f1a709f2b6f1546, after problems have been reported in the display of accounts 119/129, which leaded to an unbalanced Balance Sheet. See opw-6229773 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264923
This update resolves an issue causing incorrect balances in the French Balance Sheet reports, specifically related to accounts 119 and 129. The change reverts a previous update that introduced this imbalance, ensuring accurate financial reporting for French businesses using Odoo Enterprise.
Original PR description
This reverts commit 4ce40ed3be6981b32292d98621f1071d4a431e21, after problems have been reported in the display of accounts 119/129, which leaded to an unbalanced Balance Sheet. See opw-6229773 Forward-Port-Of: odoo/enterprise#117560
This update resolves an issue preventing monthly companies from receiving their inventory valuation journal entries. Previously, a conflicting domain in the cron job caused it to skip both monthly and daily companies. Now, the cron correctly processes both types of companies at the end of the month, ensuring accurate inventory valuation.
Original PR description
#### Description of the issue/feature this PR addresses: The "Stock Account: Inventory Valuation Closing" cron is meant to post valuation journal entries for companies configured with periodic…
#### Description of the issue/feature this PR addresses: The "Stock Account: Inventory Valuation Closing" cron is meant to post valuation journal entries for companies configured with periodic inventory valuation. Due to a faulty domain in ResCompany._cron_post_stock_valuation, monthly companies are never processed, and on the last day of the month daily companies are also skipped. As a result, no inventory valuation journal entries are ever generated by this cron for periodic-valuation companies. #### Current behavior before PR: The cron's domain requires inventory_period = 'daily', which excludes monthly companies on every non-last day of the month. On the last day of the month, an extra AND clause is added requiring inventory_period = 'monthly'. Combined with the existing 'daily' clause, this produces a contradiction (period = 'daily' AND period = 'monthly') that matches no records, so daily companies are dropped on that day as well. Net effect: monthly companies are never processed, and daily companies are skipped on month-end. #### Desired behavior after PR is merged: On a non-last day of the month, the cron processes companies with inventory_period = 'daily'. On the last day of the month, the cron processes both 'daily' and 'monthly' companies, so monthly valuation entries are posted at month-end without dropping daily companies. opw-6115649 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264298
This update fixes an issue where combo products with extra prices weren't correctly converted to the sale order's currency (MXN). Previously, the total price was inaccurate, leading to incorrect invoicing. This change ensures accurate pricing calculations for combo products in MXN, improving financial reporting.
Original PR description
The total of a sale order containing a combo product that has an extra price is not correclty converted to the sale order's pricelist currency Steps to reproduce: 1. Install Sales 2. Go to Invoicing…
The total of a sale order containing a combo product that has an extra price is not correclty converted to the sale order's pricelist currency Steps to reproduce: 1. Install Sales 2. Go to Invoicing > Configuration > Accounting > Currencies and activate currency MXN 3. Go to Sales > Products > Pricelists and create a new pricelist for currency MXN 4. Go to Sales > Products and create a new combo product "test" 5. Create a combo choice "combo" with options "Large Cabinet" and extra price 10000$ 6. Go to Sales and create a new quotation for customer Acme Corporation with product "test" (total is $10,001) 7. Change the pricelist to MXN and update prices 8. The total is ~MX$10,018 (it should be ~MX$186,682) Issue: The extra price of a combo product is not converted to the sale order's pricelist currency, so we end up adding the price of the product in the order's currency with the extra price not converted Solution: Convert the extra price of the combo product to the sale order's pricelist currency opw-6192935 Forward-Port-Of: odoo/odoo#265876 Forward-Port-Of: odoo/odoo#265008
This update resolves inconsistencies in how Odoo handles HTML parsing, specifically related to the libxml2 library. The changes ensure consistent HTML output across different versions of libxml2, improving the reliability of email templates and reports. It also addresses stricter type checking introduced in newer versions of lxml.
Original PR description
## [FIX] core: lxml compatibility v2.14.0+ (HTML parsing) In version 2.14.0, libxml2 fixed a long standing quirk in its HTML handling where it always implies `<p>` start tags [1]. As a result, there…
## [FIX] core: lxml compatibility v2.14.0+ (HTML parsing) In version 2.14.0, libxml2 fixed a long standing quirk in its HTML handling where it always implies `<p>` start tags [1]. As a result, there is a difference in behavior between pre and post 2.14.0 produced HTML when no start tag is provided: - pre: always has a `<p>` tag - post: depending on the case, could have either a `<span>` or `<p>` tag. This commit introduces a monkeypatch of the lxml's HTML parser when built with libxml2 2.14.0+ to maintain a similar behavior with older versions. [1]: https://gitlab.gnome.org/GNOME/libxml2/-/commit/8cf6129bbd836e666e7eda8c9e61c00387ae388b ## [FIX] base,l10n_it_edi: catch TypeError/ValueError for lxml 6+ compat Updates exception handling to account for stricter type checking introduced in lxml 5/6 and libxml2 2.12+. Note: Ubuntu 26.04 (Resolute) provides lxml 6.9.2/libxml2 2.15 while Debian Trixie has lxml 5.4.0/libxml2 2.9.14. Don't be fooled by the version `2.12.7+dfsg+really2.9.14-2.1+deb13u1` which actually means that Debian has reverted/held back the core engine to 2.9.14 while adding commits from 2.12.7. Forward-Port-Of: odoo/odoo#259348
This update corrects a technical issue in the FAIA report export that caused incorrect references to suppliers. Specifically, the report was incorrectly linking a supplier's ID to a customer listing due to differences in how balances are calculated. This ensures the FAIA report accurately reflects supplier information for financial reporting.
Original PR description
## Steps to reproduce: 1. Install `l10n_lu_reports`, swap to the LU company 2. Look at the partner Azure Interior. 1. They have no open balances on `asset_receivable` or `liability_payable` accounts.…
## Steps to reproduce:
1. Install `l10n_lu_reports`, swap to the LU company
2. Look at the partner Azure Interior.
1. They have no open balances on `asset_receivable` or `liability_payable` accounts.
2. Their `supplier_count` is higher than their `customer_count`.
3. Navigate to Accounting > Reporting > General Ledger.
4. Select the 2026 fiscal year.
5. Select gear > FAIA report.
6. Open the downloaded file. Notice:
1. Azure Interior is listed under /MasterFiles/Customers/Customer.
2. There are no /MasterFiles/Suppliers.
3. Azure Interior's ID (14 in this case) is referenced in a /SupplierID section.
7. Take a gander at the official XSD for LU [1]. The SupplierID must match an element in /MasterFiles/Suppliers.
Video: [2]
## Explanation
This is one of several errors found with the FAIA export. See PR #113316 for more.
It's possible to have a /SupplierID listed on a /Transaction/Line element but not have a /Suppliers/Supplier element that it refers to. This is not valid according to the FAIA report's schema [1].
This happens because /Transaction/Line and /MasterFiles use different criteria to determine if a partner is a Customer or a Supplier.
The element /Transaction/Line [3] determines this from the `partner_vals['type']` value [4]. This value is 'customer' or 'supplier' and is determined by comparing the ResPartner fields `customer_rank` and `supplier_rank`. In case of a tie, the partner is assigned as a 'supplier'.
The element /MasterFiles allows a partner to be both a Customer and a Supplier via `partner_vals['types']` [5]. Partners with an open `asset_receivable` balance at the start or end of the reporting period are listed as Customers [6]. Likewise, partners with an open `liability_payable` balance are listed as Suppliers [7]. If there are no open balances, partners are put in the Customer list by default.
The XSD validation error will not show up in a standard Runbot database because the namespace for the XSD is incorrect. If you manually fix the XSD namespace (`xmlns:doc` instead of `xmlns`) and use xmllint to check a generated XML against the XSD, it will raise the following error.
> No match found for key-sequence ['14'] of keyref 'RefGLTransactionLineSupplier'. Downloads/general_ledger (5).xml fails to validate
[1] https://pfi.public.lu/dam-assets/backup/FAIA/FAIA/XSD_Files.zip. I will note that there are three XSDs. Version A has a different namespace and appears to be more restrictive. The "full" XSD document does not raise these errors.
[2] https://drive.google.com/file/d/1xeULpCcGgZk-kYcCjBTKxcfv4ICYRzaB/view?usp=sharing
[3] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/data/saft_report.xml#L244-L248
[4] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/models/account_general_ledger.py#L299
[5] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/models/account_general_ledger.py#L303-L309
[6] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/data/saft_report.xml#L153
[7] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/data/saft_report.xml#L173
opw-6107107
Forward-Port-Of: odoo/enterprise#117799This update resolves an issue preventing users from editing tracker links. The previous code used inline styles to hide the buttons, which conflicted with newer interaction features. This change replaces inline styles with a more standard CSS class, ensuring the buttons are always visible and functional.
Original PR description
When interactions were introduced, the buttons for link tracker edition were no longer hidden by inline style, but with the class "d-none". Since there was still "display: none" as an inline style in the .xml, the buttons were never shown and the user could not edit the link code. This commit replaces the inline style by the class d-none, since it is a better practice. task-4531974 Forward-Port-Of: odoo/odoo#242481
This update ensures that vendor price selections from purchase orders are accurate, regardless of the user's timezone. Previously, the system incorrectly interpreted dates, leading to missed price matches. This fix converts dates to the user's local timezone for precise calculations.
Original PR description
opw-6211908 ## Summary When selecting a vendor price from `product.supplierinfo`, the purchase module converts `purchase.order.date_order` (a `fields.Datetime` stored in UTC) to a `date` using…
opw-6211908 ## Summary When selecting a vendor price from `product.supplierinfo`, the purchase module converts `purchase.order.date_order` (a `fields.Datetime` stored in UTC) to a `date` using Python's `.date()` method. This extracts the **UTC calendar date** rather than the user's local date. For users in positive-offset timezones (e.g. `Pacific/Auckland` UTC+12, `Africa/Johannesburg` UTC+2), this produces the wrong day, causing `product.supplierinfo` records with `date_start`/`date_end` to be incorrectly included or excluded during vendor price selection. ### Affected methods | File | Method | |------|--------| | `addons/purchase/models/purchase_order_line.py` | `_compute_selected_seller_id` | | `addons/purchase/models/purchase_order_line.py` | `_prepare_purchase_order_line` | | `addons/purchase/models/purchase_order.py` | `_get_product_catalog_lines_data` | ### Fix Replace `.date()` calls with `fields.Date.context_today(record, timestamp=...)` which correctly converts the UTC datetime to the user's timezone before extracting the date. Also fixes `fields.Date.today()` → `fields.Date.context_today(self)` in `_prepare_purchase_order_line` for consistency (same issue — `fields.Date.today()` returns UTC date, not the user's local date). ## Steps to reproduce 1. Set user timezone to **Pacific/Auckland** (UTC+12). 2. Create a product with a vendor pricelist (`product.supplierinfo`) entry: - **Vendor**: any partner - **Price**: 50.00 - **Start Date**: 2026-05-13 - **End Date**: 2026-05-31 3. Create a **Purchase Order** for that vendor. 4. Set the **Order Deadline** to **2026-05-13 08:00** NZST (stored as `2026-05-12 20:00 UTC`). 5. Add the product as a line on the PO. **Expected**: The supplier price of 50.00 is selected — the user's local date (May 13) is within the validity window. **Actual**: No supplier price is matched. `.date()` on the UTC datetime returns `2026-05-12`, which is before `date_start` of `2026-05-13`, so the supplierinfo record is skipped. Forward-Port-Of: odoo/odoo#263992
This update resolves a problem where Xrechnung invoices generated in Odoo were failing validation checks used by some German clients. The issue stemmed from incorrect PDF formatting, preventing the invoices from meeting required standards. This fix ensures Odoo invoices comply with German client validation requirements.
Original PR description
**PROBLEM** xrechnung pdf invoices are not compliant with some validators used german clients. **STEP TO REPRODUCE** 1. Create an invoice for a german customer. 2. Set the edi format on the customer as Xrechnung. 3. Download the invoice pdf, and verify it on https://www.portinvoice.com/ 4. Notice the pdf is not valid. To verify my fix works, you need to have the fontTools python package installed (for pdfa conversion). opw-6030481 Forward-Port-Of: odoo/odoo#259318
This update improves the speed of creating taxes in Odoo, particularly when dealing with very large databases. Previously, a check to ensure a tax wasn't already in use slowed down the process. Now, this check is skipped during tax creation, significantly reducing creation times.
Original PR description
On large databases (with millions on move lines), creating a tax can become very slow because of the consistency check that validate that the tax is not used on move line of another company. As there could not be any usage of a tax before its creation, we simply skip that check on creation. opw-5914312 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260592
This update corrects a bug in Odoo 18/19 where purchase order move lines incorrectly defaulted to the main warehouse location instead of the intended sub-location when a specific destination was configured. By prioritizing the sub-location destination, this ensures forecasted quantities are accurately calculated, improving inventory planning and reporting. This fix impacts the 1-step receiving process.
Original PR description
### **Description of the issue/feature this PR addresses:** **Issue:** In Odoo 18/19, purchase move lines default to the WH's main stock location (`lot_stock_id`) as the `location_final_id`. However,…
### **Description of the issue/feature this PR addresses:** **Issue:** In Odoo 18/19, purchase move lines default to the WH's main stock location (`lot_stock_id`) as the `location_final_id`. However, when a user configures a sub-location on the Receipt Operation Type, the picking destination is correct, but the move lines are defaulted to the main warehouse. This mismatch causes the Forecasted Quantity to not increment for the intended sub-location **Solution:** Prioritize the `default_location_dest_id` before falling back to the default stock location opw-6032018 ### **Current behavior before PR:** When confirming a PO, the `location_final_id` on stock moves defaults to the `lot_stock_id`, regardless of the specific destination set on the Operation Type. This causes a mismatch in 1-step receiving flows where a sub-location (e.g., WH/Stock/Test) is intended, since the move lines revert to the root warehouse location (WH/Stock). Thus, the forecasted quantity for the specific sub-location doesn't increment as expected. ### **Desired behavior after PR is merged:** The `_get_final_location_record` method will now evaluate if the Operation Type's `default_location_dest_id` is a child of the warehouse's main stock. If it is, the sub-location is used as the `location_final_id` for the moves and move lines. This ensures that the forecasted quantity reflects the intended destination upon PO confirmation while still maintaining the fallback to the warehouse root for standard multi-step routes. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259233 Forward-Port-Of: odoo/odoo#254527