Daily updates from Odoo
Tuesday, April 14, 2026
255 changes
20 changes
New functionality added to Odoo
This update creates a specific work entry type for sick time off in Belgium where a certificate isn't required. Previously, all sick time off types shared a single entry, leading to inconsistencies. This change ensures accurate tracking of different sick time off scenarios.
Original PR description
Before merging time off type and work entry type, we had both sick time off and sick time off without certificate pointing to the same work entry type, which can not be the case now as each time off type maps to exactly one work entry type. This commit adds a dedicated work entry for the Belgian sick time off without certificate. task-6110080
This update allows users to efficiently update the partner associated with multiple invoices or move records directly from a list view. Previously, changing this information required individual updates for each record. This enhancement improves workflow efficiency for bulk partner adjustments.
Original PR description
[IMP] account: mass edit partner on move list This commit adds the feature to mass edit the partner field on moves when the user is in a move list view. A widget is created to display either the Many2one `partner_id` field (in case we're editing multiple moves) or the `invoice_partner_display_name` (in case we're displaying without editing) task-5986025 Forward-Port-Of: odoo/odoo#254340
Enhancements to existing features
This update brings the software running on our IoT boxes to version 19.2, aligning them with the latest Odoo release. This ensures our IoT devices receive the newest features and improvements, and will be updated within two weeks of this merge.
Original PR description
This PR updates the current version of the iot boxes to saas-19.2. This only applies to the iot boxes currently in saas-19.1 This will lead to the iot boxes updating to the next version 2 weeks after this PR is merged task-5949470 Forward-Port-Of: odoo/odoo#258140
This update enhances the system's ability to identify duplicate accounting moves, providing clearer visual cues for users. The system now highlights potential duplicates in red or yellow based on similarity, and prioritizes warnings based on move status (Draft vs. Posted).
Original PR description
In this commit: - Highlight the reference in red when it is identical and in yellow when references are different. Apply the same logic to the duplicate document warning in the form view. - In the form view duplicate warning, use the Bill Reference if available, then the Move Name, then "Draft". - Yellow warnings are restricted to Draft moves; only red warnings remain visible once Posted. task-5916255 Forward-Port-Of: odoo/odoo#248421
Resolved issues and error corrections
This update fixes an issue where duration calculations were incorrectly rounding minutes and seconds, sometimes resulting in durations being displayed as '60 minutes' instead of '1 hour'. The change ensures durations are accurately formatted for display, improving the user experience.
Original PR description
Before this commit, when the minutes of a duration go through Math.round, it can return 60 minutes in the duration instead of 1h. The same issue go for the seconds too. Now, the formatDuration check if this cases happen and and ajust the result of the rounding if necessary. TASK-6107266 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
A recent update to the MRP module introduced a test failure in our builds. This change was caused by a new field (`backorder_ids`) added in the `stock_barcode_mrp` module. This fix ensures the test runs correctly without requiring the enterprise module, maintaining stability and preventing potential disruptions.
Original PR description
The test `test_basic_flow_with_minimal_access_rigths` fails in builds without `stock_barcode_mrp` since the `backorder_ids` mrp.production field is introduced in that module: https://github.com/odoo/enterprise/blob/92c584cc1426ac70f6f77aa8216c17004fa42d35/stock_barcode_mrp/models/mrp_production.py#L10 runbot-242465 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258837
This update resolves an issue where kit products were incorrectly rounding purchase order values due to how the cost share was calculated. The fix ensures that kit product costs are distributed accurately, preventing valuation discrepancies and improving the reliability of purchase order calculations. This impacts how kit products are valued during the ordering process.
Original PR description
### Steps to reproduce: - Create a kit product with 6 bom lines (with a `cost_share` of `0.0%`) - Create + confirm a purchase order for 1 unit of the kit product at 60 - Validate the delivery #### >…
### Steps to reproduce: - Create a kit product with 6 bom lines (with a `cost_share` of `0.0%`) - Create + confirm a purchase order for 1 unit of the kit product at 60 - Validate the delivery #### > 6 layers were created with values 9.99, 10, 10, 10, 10 and 10 There are two issues with purchased kit valuation addressed in this PR: ### Issue 1: Since 8c199f7783527735b35c9fbda334cbdcd55a004f, the product price unit is not supposed to be rounded anymore. However, kit products rely on the rounded `cost_share` field of the `mrp.bom.line` to determine which part of the price of the kit product is handled by which component: https://github.com/odoo/odoo/blob/591102ff37fef1f0b9a946fee3f9d85789653e65/addons/mrp/models/stock_move.py#L245-L246 https://github.com/odoo/odoo/blob/591102ff37fef1f0b9a946fee3f9d85789653e65/addons/purchase_mrp/models/stock_move.py#L28 https://github.com/odoo/odoo/blob/591102ff37fef1f0b9a946fee3f9d85789653e65/addons/purchase_mrp/models/stock_move.py#L38 This leads to inevitable rounding issues where `60/6` does not match `10`: https://github.com/odoo/odoo/blob/591102ff37fef1f0b9a946fee3f9d85789653e65/addons/purchase_mrp/tests/test_purchase_mrp_flow.py#L1273-L1275 simply because 1/6 is represented as `16.67%` and not by `16.66666666666666%`. However, values such as 1/6 can be obtained if you do not set any `cost_share`, since the kit explosion will equidistribute its cost share: https://github.com/odoo/odoo/blob/591102ff37fef1f0b9a946fee3f9d85789653e65/addons/purchase_mrp/models/mrp_bom.py#L42-L48 ### Fix of this issue: We set the digits to `False` for stability reason as the columns have been initiallised as "numeric" values and needs to stay numeric: https://github.com/odoo/odoo/blob/b007b0a4f7e56f6dc44df3154e13745c9981eae3/odoo/fields.py#L1627-L1650 Note that when the digit is Falsy on the field, the field value is formatted to the second digit by the front end: https://github.com/odoo/odoo/blob/3542c542eac5b204e69a8dd6ae1907cfcef60af3/addons/web/static/src/views/fields/float/float_field.js#L58-L76 https://github.com/odoo/odoo/blob/12e453302a950df4d9ee45954f54bdf610888eda/addons/web/static/src/core/utils/numbers.js#L214-L227 In particular, when we create the bom and set the `cost_share`, all possible values will be rounded to the second decimal just as before. This change will therefore only alter the rounding behavior in the DB for equidistributed values such as `16.66666666666666%`. ### Issue 2: While the value of the kit product is exploded and distributed among components, the values of each individual `stock.valuation.layer` are themselves rounded before creation based on the company currency: https://github.com/odoo/odoo/blob/4188436a9e800b062bf9f3b0055cad86acc47e19/addons/stock_account/models/product.py#L240-L255 https://github.com/odoo/odoo/blob/4188436a9e800b062bf9f3b0055cad86acc47e19/addons/stock_account/models/stock_valuation_layer.py#L30 Now, this is problematic since the sum of the values of the layers is expected to match the total value of the purchase order line (that is, the non-rounded value of the components of the purchased kit). ### Fix of this issue: We compute and distribute the rounding error among layers corresponding to the purchased kit product before creation (since layer values are not expected to be modified afterwards), based on the non-rounded computation, since this value should now be exact (as the unit cost is not rounded anymore). opw-5085457 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257411 Forward-Port-Of: odoo/odoo#252034
This update fixes an issue where stock lot generation incorrectly used the standard product UoM (Unit) instead of the sales packaging UoM (Pack of 6). The change ensures that lots are created with the correct quantity based on the product's sales packaging, improving inventory accuracy. This resolves a discrepancy in lot quantities.
Original PR description
Steps to reproduce the issue:
- Enable "Units of Measure" and "Lots & Serial Numbers" in the inventory settings
- Create a storable product "P1":
- Tracking: Lot
- UoM: Unit
- Sales tab: Packagings > Pack of 6
- Create a receipt with 3 packs of 6 of P1
- Mark it as "To Do"
- Open the detailed operations and click on the "Generate Serials/Lots" button:
- First lot: Lot 1
- Quantity per Lot: 3 packs of 6
- Quantity received: 3 packs of 6
- Click on "Generate"
Problem:
A stock move line is created with 3 units instead of 3 packs of 6, because the UoM is not passed from the JavaScript side to the Python side. As a result, the default product UoM (Unit) is used.
opw-5933277
Forward-Port-Of: odoo/odoo#258392This update corrects a technical issue preventing proper import of Nilvera electronic invoices. The team renamed a method in the core Odoo system to align with a recent change. This fix ensures that Nilvera invoices are now correctly processed and imported into Odoo.
Original PR description
# Description of the issue/feature this PR addresses The parent class `account.edi.xml.ubl_20` renamed `_import_fill_invoice_form` to `_import_fill_invoice`. The override in `l10n_tr_nilvera_einvoice` was not updated to match, causing the override to be silently ignored. # Current behavior before PR The `_import_fill_invoice_form` override in `l10n_tr_nilvera_einvoice` is never called because the parent method no longer exists under that name. # Desired behavior after PR is merged The override is renamed to `_import_fill_invoice` to match the parent class, restoring correct behaviour for Nilvera invoice imports. task-id: None --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258752 Forward-Port-Of: odoo/odoo#258097
This update resolves an issue where spreadsheet list views were showing technical field names instead of user-friendly labels. The change ensures that all fields, including list headers, are correctly fetched and displayed in the spreadsheet. This improves the overall user experience and data clarity.
Original PR description
The `ODOO.LIST.HEADER` formula will display the technical name of the field instead of its albels if there are no `ODOO.LIST` formulas for that same field. Since the introduction of chaining fields in list formulas, the fields we want to fetch should be added to `fieldPathsToFetch` in the data source. But this was only done for the `ODOO.LIST` formula, not for `ODOO.LIST.HEADER`. Task: [5900769](https://www.odoo.com/web#id=5900769&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) 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#258400 Forward-Port-Of: odoo/odoo#257087
This update ensures that receipt images, such as the logo and QR codes, are always correctly printed. Previously, images were sometimes missing due to a timing issue where the receipt was generated before the images had fully loaded. This change uses a utility to wait for images to load, guaranteeing a complete and accurate receipt.
Original PR description
The receipt logo (and other images like QR codes) was sometimes missing from the printed ticket. This happened intermittently because the receipt image was being generated (captured from an iframe) before the browser had finished decoding and rendering the logo image within that iframe. This commit updates PosTicketPrinterService to use the waitImages utility, ensuring that all images in the receipt's iframe are fully loaded and rendered before returning the iframe for further processing (printing or canvas capture). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a previous restriction in how the system identifies Spanish freelancers. Specifically, it now recognizes 'Comunidades de Bienes' (CBs) – entities taxed as freelancers – which were previously excluded due to a limited regex. This ensures accurate fiscal categorization and reporting for these businesses.
Original PR description
In Spain, "Comunidades de Bienes" (VAT starting with 'E') are entities without legal personality that tax via income attribution to their members. For accounting and tax reporting purposes, they must be treated as individuals/freelancers rather than corporations. The current _l10n_es_freelancer logic was too restrictive, only matching standard DNI (8 digits + letter) or NIE (starting with X, Y, Z). This caused CBs to be excluded from freelancer-specific logic, leading to incorrect fiscal categorization in reports and tax modules. The regex has been updated to optionally allow the 'E' prefix while ensuring the rest of the string maintains a valid format, effectively broadening the scope of what the system considers a Spanish freelancer. task-6014192 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258474 Forward-Port-Of: odoo/odoo#253087
This update resolves an issue preventing the creation of product feeds when only one website is enabled in the database. The fix ensures a default website ID is assigned, allowing the system to correctly link product feeds with the appropriate language. This ensures all merchants can utilize product feeds, regardless of their website setup.
Original PR description
Issue: --- Due to this issue, we cannot create a `product.feed` record in single website db. Steps to reproduce: 1- Create a fresh db with single website. 2- Enable Google Merchant Center. 3- Try to create a `website.feed` record. It's not possible to create the record due to language field. Cause: --- `website_id` is only shown in `group_multi_website`. When there is only one website set, there is no default value for the website. `lang_id`'s domain is also `website_id.language_ids`, as a result record creation will fail. opw-6110843 Forward-Port-Of: odoo/odoo#258653
This change removes a restriction that prevented users from accessing tax returns when the GST e-filing feature was disabled. Previously, a warning forced users to enable the feature, which wasn't always necessary. Now, users can access all tax returns regardless of the GST e-filing setting.
Original PR description
BEFORE: - Before this commit, when we disable the gst e-filing feature from the configuration and try to access the tax return view, we are getting blocked by the redirect warning, which suggests…
BEFORE: - Before this commit, when we disable the gst e-filing feature from the configuration and try to access the tax return view, we are getting blocked by the redirect warning, which suggests enabling the gst e-filing feature from the configuration. - Which is not desirable, as there might be some returns that are not related to gst e-filing, which should be accessible by the user. AFTER: - After this commit, removed the RedirectWarning when accessing the tax return view with gst e-filing feature disabled. So now the user can access tax returns without enabling gst e-filing feature. - At the time of setting the fiscal year(generating/refreshing returns automatically), the GSTR returns will not be created. - And at the time of manual GSTR return creation, we are raising UserError to instruct the user about enabling the gst e-filing feature. Related Ent PR: https://github.com/odoo/enterprise/pull/105983 Task-5486586 Forward-Port-Of: odoo/odoo#259029 Forward-Port-Of: odoo/odoo#247216
This update resolves an issue where hidden fields within form blocks added to Masonry blocks were still visible. The fix involves applying a higher priority CSS rule to ensure the 'display: none' style is consistently applied, preventing it from being overridden. This ensures that hidden fields truly disappear as intended.
Original PR description
# How to reproduce - Go to the website editor - Add a Masonry block - Add a Form inner block in the Masonry block - Select any fields of the form - Set it's visibility to Hidden - Save # The problem…
# How to reproduce - Go to the website editor - Add a Masonry block - Add a Form inner block in the Masonry block - Select any fields of the form - Set it's visibility to Hidden - Save # The problem The field is still visible. # Cause When a field has its visibility set to hidden, it is applied the `.s_website_form_field_hidden` CSS class which applies `display: none`. https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/website/static/src/snippets/s_website_form/001.scss#L26-L28 But that CSS rule is overriden by the masonry's `.s_masonry_block[data-vcss='001'] .row > div` CSS class. https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/website/static/src/snippets/s_masonry_block/001.scss#L1-L3 https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/website/static/src/scss/website.scss#L3246 # Proposed solution We set `display: none` with `!important` to prevent it from being overidden. We also need to add `!important` to its edit mode counter-part so that the field is still visible in that mode. opw-6038955 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256100
This update resolves an issue where a task created without a project would trigger an error due to a required field. The fix ensures that widgets correctly handle task creation without unintended dependencies, improving the user experience when creating tasks without a project association.
Original PR description
Example of steps: - Install todo module - Create a todo task (it will be created without project_id) - Go to project -> my task - You can see your previously created todo task (with project set as) -…
Example of steps:
- Install todo module
- Create a todo task (it will be created without project_id)
- Go to project -> my task
- You can see your previously created todo task (with project set as)
- This todo task is marked as Private (since no project)
- Refresh page
- There is now an error because project is now required and you cannot save the current task
This problem is caused by `addFieldDependencies` from `relational_model/utils` Let's simplify the case with this view for example:
```xml
<form>
<field name="foo" widget="my_widget"/>
<field name="name" />
<field name="child_ids">
<list editable="top">
<field name="foo" widget="my_widget"/>
<field name="name" required="1"/>
</list>
</field>
</form>
```
my_widget is defined with these fieldDependencies:
```js
[
{
name: "name",
type: "char",
}
]
```
We have twice the same group of fields (name + foo with my_widget), one in the form view and the other one in the subview list (child_ids).
Currently, we firstly process subviews in `addFieldDependencies`. As "name" field is used in dependencies of `my_widget` and name is already use in the same view (subview list) with required="1" we will change `my_widget` dependencies to be required too by mutating `widget.fieldDependencies`.
And after, we will do the same with the main form view, but as fieldDependencies object from fieldInfo is the same for every instances of the widget everywhere (from form arch parser), we should not alter it because we might accidentally add attributes to certain fields (for example, in our case, making the “name” field in the main view required when it shouldn't be).
This commit fix this case by using a spread operator to shallow copy fieldDependencies items.
opw-6008266
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#258654This update fixes an issue where newly created stock move lines in the picking view would disappear after a refresh. The fix dynamically updates the view to always show all move lines associated with a specific picking, ensuring accurate inventory tracking and preventing data loss.
Original PR description
**Problem:** When creating a new stock.move.line in the moves view (accessed via smart button from a picking), the newly created line disappears after any refresh action (manual refresh or triggering…
**Problem:**
When creating a new stock.move.line in the moves view (accessed via smart button from a picking), the newly created line disappears after any refresh action (manual refresh or triggering "Put in Pack").
**Steps to reproduce:**
1. Open a receipt/picking operation
2. Click on the "Moves" smart button to open the detailed operations view
3. Create a new stock.move.line record
4. Click "Put in Pack" or manually refresh the page
5. Observe that the newly created line disappears
**Current behavior:**
The newly created stock.move.line disappears from the view after refresh, and only reappears if you navigate back to the picking and then return to the moves view.
**Expected behavior:**
The newly created stock.move.line should remain visible in the view after refresh or any action that triggers a view reload.
**Cause of the issue:**
The action_detailed_operations method uses a static domain [('id', 'in', self.move_line_ids.ids)] that captures a snapshot of move line IDs at the moment the action is opened.
https://github.com/odoo/odoo/blob/22ac818970f104a732cc7d24afc440cf0e6d74bd/addons/stock/models/stock_picking.py#L1204-L1212 When a new stock.move.line is created in this view, its ID is not included in the original static list. Any refresh (manual or triggered by operations like "Put in Pack") re-applies this static domain, filtering out the newly created lines because their IDs weren't captured in the initial list.
**Fix:**
Using a dynamic domain based on picking_id ensures all move lines belonging to the picking are always visible, regardless of when they were created. This aligns with the expected behavior of showing "all move lines for this picking" rather than "only the move lines that existed when the view was opened". The relational lookup [('picking_id', '=', self.id)] is re-evaluated on each refresh, automatically including any newly created lines that have the correct picking_id set.
opw-5398620
Forward-Port-Of: odoo/odoo#251619
Forward-Port-Of: odoo/odoo#247170This update fixes an issue where sales orders with fully delivered and returned products incorrectly displayed as 'Fully Invoiced'. The fix ensures the invoice status accurately reflects zero delivered and invoiced quantities after a customer returns a product, preventing incorrect invoicing and improving order accuracy. This resolves a potential discrepancy in reported sales data.
Original PR description
### Issue before this commit: When a sales order with a product invoiced on delivered quantities is fully delivered and then completely returned the delivered quantity is reset to zero. In this…
### Issue before this commit: When a sales order with a product invoiced on delivered quantities is fully delivered and then completely returned the delivered quantity is reset to zero. In this situation, where nothing has been invoiced and nothing remains to be invoiced, the invoice status of the sales order line is incorrectly set to "Fully Invoiced" instead of "Nothing to Invoice". ### Steps to reproduce the issue: 1. Create a new quotation for a storable product. 2. Confirm the order. 3. Validate the delivery of the product. 4. Perform a return for the product 5. Validate that return to simulate a customer return. 6. The sales order details correctly reflect that the delivered quantity and invoiced quantity are both zero. Despite these values—which indicate there is nothing to invoice—the invoice status on the quotation erroneously displays as "fully invoiced". ### Cause of the issue: The invoice status computation includes a fallback logic that marks a sales order line as "invoiced" when all related stock moves are either done or cancelled. However, this logic does not verify whether any quantity remains effectively delivered. As a result, after a full return, even when qty_delivered = 0, the condition is still met and the line is incorrectly marked as fully invoiced. ### Reason to introduce the fix: A fully returned sales order line with no delivered and no invoiced quantity should not be considered fully invoiced. The fix ensures that the fallback to "invoiced" only applies when there is a strictly positive delivered quantity, preventing incorrect invoice status after full customer returns. opw-6014772 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258589 Forward-Port-Of: odoo/odoo#254871
This update resolves a stability issue in the spreadsheet pivot feature. Previously, the system incorrectly relied on a single field property, leading to crashes when encountering certain field types (like JSON). The fix ensures the system correctly identifies unsupported field types, preventing errors and improving the overall reliability of the spreadsheet pivot functionality.
Original PR description
Spreadsheet pivots only do not support all field types. But we were relying only on `field.groupable` to determine if a field could be grouped, which is wrong (eg. JSON fields can be groupable but are not supported). It leads to crashes for fields that were groupable, but didn't have an entry in `pivotNormalizationValueRegistry`. Added a test for all of the field types to ensure we have a correct behavior. Task: 6036075 Task: [6036075](https://www.odoo.com/odoo/2328/tasks/6036075) 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#258883 Forward-Port-Of: odoo/odoo#255571
This update corrects a previous issue where delivery slip prices were incorrectly displayed in the company currency instead of the customer's order currency. The change ensures that commercial invoices and delivery slips accurately reflect the price of goods in the correct currency, improving financial reporting and customer billing. This was caused by a bug introduced in a previous update.
Original PR description
The product value reported on delivery slips may incorrectly use the company currency instead of the order currency. Steps to reproduce: - Enable multi-currency and create a foreign currency - Create a pricelist in the foreign currency - Create and confirm a Sale Order using that pricelist - Add a delivery via carrier (eg. Fedex) - Confirm the delivery and generate the commercial invoice. Issue: The 'sale_price' on the stock move lines is taken in company currency rather than order currency. opw-6104130 Forward-Port-Of: odoo/odoo#259020 Forward-Port-Of: odoo/odoo#258875
15 changes
New functionality added to Odoo
This update allows users to split a single production order into multiple serial numbers, addressing a limitation introduced in a previous update. Previously, generating multiple serial numbers was restricted to one order at a time. Now, a new button in the serial number generation wizard enables users to create individual serial numbers for each sub-order, improving traceability and flexibility in managing production runs.
Original PR description
Since 4bb4e08066449, producing multiple serial that have been generated is only doable on one mo. We can split mo. we can generate serial number but we cannot do both at the same time. This commit adds a new button into the generate serial wizard to split the main mo into the number of serial wanted and attribute one for each sub mo. 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#255577
This update allows users to efficiently change the partner associated with multiple invoices or move records directly from a list view. Previously, changing this field required individual updates for each record. This enhancement improves workflow efficiency and data accuracy.
Original PR description
[IMP] account: mass edit partner on move list This commit adds the feature to mass edit the partner field on moves when the user is in a move list view. A widget is created to display either the Many2one `partner_id` field (in case we're editing multiple moves) or the `invoice_partner_display_name` (in case we're displaying without editing) task-5986025
Enhancements to existing features
This update enhances the system's ability to detect duplicate accounting moves, providing clearer visual cues for users. The system now highlights identical references in red and different ones in yellow, and warnings are restricted to 'Draft' moves, ensuring accuracy and reducing confusion.
Original PR description
In this commit: - Highlight the reference in red when it is identical and in yellow when references are different. Apply the same logic to the duplicate document warning in the form view. - In the form view duplicate warning, use the Bill Reference if available, then the Move Name, then "Draft". - Yellow warnings are restricted to Draft moves; only red warnings remain visible once Posted. task-5916255 Forward-Port-Of: odoo/odoo#248421
Resolved issues and error corrections
This update resolves an issue where Point of Sale users couldn't successfully refresh their Viva.com payment tokens, leading to errors when making payments. The fix ensures that the refreshed token is persistently stored, allowing Viva payments to continue working smoothly even after the initial token expires or is invalidated.
Original PR description
Point of Sale users only have read access on pos.payment.method. When the stored Viva.com bearer token expires or the API returns invalid credentials, _bearer_token() fetches a new token . That write ran as the POS user and raised an AccessError, although the user was only paying—not editing configuration. Steps to reproduce: ------------------- * Configure Viva.com as payment method. * Open the POS as a user with only Point of Sale / User (not Administrator). * Pay with Viva until the OAuth token must be refreshed (e.g. after expiry or after Viva rejects the current token). > Observation: AccessError: You are not allowed to modify 'Point of Sale Payment Methods' (pos.payment.method) records. Why the fix: ------------ Persist the refreshed viva_com_bearer_token with sudo().write() so the ORM does not require write ACL on pos.payment.method for that internal side effect of an already authorized Viva RPC. opw-6078131 Forward-Port-Of: odoo/odoo#257842
This update resolves an issue where the size of images, especially those protected by CORS, was incorrectly displayed in the website builder. The fix accurately determines image size by retrieving information from the server, ensuring correct size representation for all images, regardless of their origin.
Original PR description
[FIX] html_builder, *: hide the size of CORS-protected images *: html_editor Steps to reproduce: - Add an image on the website. - Replace it with a CORS-protected image. -> The image options display…
[FIX] html_builder, *: hide the size of CORS-protected images *: html_editor Steps to reproduce: - Add an image on the website. - Replace it with a CORS-protected image. -> The image options display a size, but it is incorrect. The problem is that it is not the real size of the image but the size of a default image (due to it, if you replace the image by another CORS protected one, you'll see that the size of the image remains the same). Indeed, the size of an image (in bytes) is computed from the length of the raw b64 content of the image, on which a ratio of 3/4 is applied. Because the image is CORS protected, we can not retrieve the raw b64 of the image so the image size should not be displayed. This commit hides the size of CORS protected image as it is impossible to retrieve. Note: example of a CORS protected image: https://tinyjpg.com/images/social/website.jpg task-5405262 --------------------------------------------------------------------------------------------------------------------------------------------- [FIX] html_builder, *: correctly determine image mimetype *: html_editor The goal of this commit is to improve the way the mimetype of an image is determined if the information is not in the DOM. Before this commit, the system relied on the extension of the image source to determine its mimetype. This is not really robust and it is easily trickable. For example, in `html_editor`, if an image in a html field comes from an attachment, its `src` attribute will end by the attachment name. If a user changes the attachment name extension, the next time the image is added on the DOM, the extension is changed but the mimetype of the image is unchanged. To solve the problem, the mimetype of the image is determined thanks to the headers of the http request to the `src` of the image. That way, the information comes from the server hosting the image. task-5405262 --------------------------------------------------------------------------------------------------------------------------------------------- [FIX] html_builder, website: enable the quality change on shaped img This commit improves [this one] by adding a test (this commit was created before [this one] was merged). It also improves it; the `mimetypeBeforeConversion` is either retrieved from the dataset or from a `loadImageInfo` if the information is not on the dataset. [this one]: https://github.com/odoo/odoo/commit/738d5fb5ae2154e1f6993817fab5471d2d4384fa task-5405262 --------------------------------------------------------------------------------------------------------------------------------------------- [FIX] html_builder, *: hide shape option for CORS-protected images *: website Steps to reproduce the problem: - Add an image on the page. - Replace the image by a CORS protected one. - Try to apply a shape on the image. -> Traceback The goal of this commit is to hide the "Shape" option if the "original image" of an image is not retrievable. Indeed, in this case, the option will fail to apply correctly. task-5405262 --------------------------------------------------------------------------------------------------------------------------------------------- [FIX] html_builder, *: avoid displaying options that are not compatible *: html_editor, website Few options like filter, quality, format and cropping rely on canvas to work. The problem is that it does not work correctly for mimetypes like `svg` or `gif`. Indeed, if an image modification is done on such images, it will automatically be transformed into a `png` by default. To avoid it, this commit hides the options that rely on a canvas manipulation when clicking on a `svg` or `gif` image. The process image function has also been adapted to not try to transform an image if its mimetype is not compatible with a canvas transformation. Instead, those images are directly transformed into `b64` images without any transformation. Thanks to it, a shape can be applied on a `svg` or a `gif`. task-5405262 --------------------------------------------------------------------------------------------------------------------------------------------- [FIX] html_builder, *: apply shape on replaced svg and gif images *: website Steps to reproduce the problem: - Add a "Text-Image" snippet on the page and add a shape on the image. - Replace the image by a svg or a gif. -> A shape is displayed on the image options but the shape is not applied on the image. task-5405262 --------------------------------------------------------------------------------------------------------------------------------------------- [FIX] html_builder, *: avoid copying options on new incompatible images *: html_editor, website Steps to reproduce: - Add an image on the website. - Add a shape on the image. - Replace the image by a CORS-protected one. -> The image still has the shape data attributes on its HTML element while it should not as it does not have the prerequisites to have a shape (it does not have an original source). The same problem exists with the hover effect. This commit moves the logic that transfers the shape and hover effect on replaced images from `html_editor` to the responsible plugins in `html_builder` and `website`. It also adds a check to verify that the replaced image is eligible to have a particular option before transferring its data information. task-5405262 Forward-Port-Of: odoo/odoo#258798 Forward-Port-Of: odoo/odoo#251703
This update fixes an issue where the leave balance report was incorrectly calculating employee leave accruals and usage, particularly with overlapping leave periods. The fix ensures accurate reporting by addressing timezone discrepancies and improving how leave allocations are tracked, leading to more reliable leave data.
Original PR description
__ISSUE__: - FIFO balance miscalculation for non-overlapping allocations. cumulative_allocated_days was partitioned globally by (employee, leave_type), but taken_per_allocation scoped leaves to each…
__ISSUE__:
- FIFO balance miscalculation for non-overlapping allocations. cumulative_allocated_days was partitioned globally by (employee, leave_type), but taken_per_allocation scoped leaves to each allocation's date range. This caused the FIFO formula to silently absorb leaves from one period into another's allocation capacity.
ex:
Alloc A (20 days) 2025, taken leaves 15 days
Alloc B (20 days) 2026, taken leaves 5 days
report: 2025: (15 taken), (5 left)
2026: (7 taken), (20 left)
- Left" rows shifted by one year in non-UTC timezones. Allocation date_from/date_to (Date fields) were cast to timestamp as midnight UTC. In negative-UTC /positive-UTC timezones midnight UTC of Dec 31 renders as the prev/next day.
__FIX__:
- detect overlap groups using a running MAX(date_to) and partition the cumulative sums within each overlap group. This way non-overlapping allocations are treated as independent, while overlapping or open-ended allocations still share FIFO within their group.
- offset allocation dates by 12 hours so no timezone can shift them across a day boundary.
- opw-5169606
- opw-5352114
Forward-Port-Of: odoo/odoo#257873This update resolves an issue where spreadsheet list views were showing technical field names instead of user-friendly labels. The fix ensures that list headers now accurately display the correct field names, improving the user experience when viewing data in spreadsheets. This was necessary due to recent changes in how fields are handled in list formulas.
Original PR description
The `ODOO.LIST.HEADER` formula will display the technical name of the field instead of its albels if there are no `ODOO.LIST` formulas for that same field. Since the introduction of chaining fields in list formulas, the fields we want to fetch should be added to `fieldPathsToFetch` in the data source. But this was only done for the `ODOO.LIST` formula, not for `ODOO.LIST.HEADER`. Task: [5900769](https://www.odoo.com/web#id=5900769&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) 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#258400 Forward-Port-Of: odoo/odoo#257087
This update fixes an issue where sales orders with fully delivered and returned products incorrectly displayed as 'Fully Invoiced'. The fix ensures that the invoice status accurately reflects zero delivered and invoiced quantities after a customer returns a product, preventing incorrect invoicing and improving order accuracy.
Original PR description
### Issue before this commit: When a sales order with a product invoiced on delivered quantities is fully delivered and then completely returned the delivered quantity is reset to zero. In this…
### Issue before this commit: When a sales order with a product invoiced on delivered quantities is fully delivered and then completely returned the delivered quantity is reset to zero. In this situation, where nothing has been invoiced and nothing remains to be invoiced, the invoice status of the sales order line is incorrectly set to "Fully Invoiced" instead of "Nothing to Invoice". ### Steps to reproduce the issue: 1. Create a new quotation for a storable product. 2. Confirm the order. 3. Validate the delivery of the product. 4. Perform a return for the product 5. Validate that return to simulate a customer return. 6. The sales order details correctly reflect that the delivered quantity and invoiced quantity are both zero. Despite these values—which indicate there is nothing to invoice—the invoice status on the quotation erroneously displays as "fully invoiced". ### Cause of the issue: The invoice status computation includes a fallback logic that marks a sales order line as "invoiced" when all related stock moves are either done or cancelled. However, this logic does not verify whether any quantity remains effectively delivered. As a result, after a full return, even when qty_delivered = 0, the condition is still met and the line is incorrectly marked as fully invoiced. ### Reason to introduce the fix: A fully returned sales order line with no delivered and no invoiced quantity should not be considered fully invoiced. The fix ensures that the fallback to "invoiced" only applies when there is a strictly positive delivered quantity, preventing incorrect invoice status after full customer returns. opw-6014772 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258589 Forward-Port-Of: odoo/odoo#254871
This update corrects a previous restriction in how the system identifies Spanish freelancers, specifically for "Comunidades de Bienes" (CBs) with an 'E' VAT prefix. Previously, these entities were incorrectly categorized, leading to potential errors in tax reporting. The change broadens the system's recognition of Spanish freelancers, ensuring accurate fiscal categorization.
Original PR description
In Spain, "Comunidades de Bienes" (VAT starting with 'E') are entities without legal personality that tax via income attribution to their members. For accounting and tax reporting purposes, they must be treated as individuals/freelancers rather than corporations. The current _l10n_es_freelancer logic was too restrictive, only matching standard DNI (8 digits + letter) or NIE (starting with X, Y, Z). This caused CBs to be excluded from freelancer-specific logic, leading to incorrect fiscal categorization in reports and tax modules. The regex has been updated to optionally allow the 'E' prefix while ensuring the rest of the string maintains a valid format, effectively broadening the scope of what the system considers a Spanish freelancer. task-6014192 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258474 Forward-Port-Of: odoo/odoo#253087
This update fixes an issue where discount amounts on POS session reports were calculated incorrectly. The fix ensures that taxes are applied *after* the fiscal position, resulting in accurate discount calculations and reporting. This improves the reliability of financial reports generated from point-of-sale transactions.
Original PR description
Steps: ---- - Create a fiscal position with 2 different taxes - Add a line in POS - Apply fiscal position and add line discount - Finish the order cycle - Download the session report Issue: ---- - The discount amount was calculated incorrectly in the session report Cause: ---- - The discount amount calculation used taxes before applying the fiscal position Fix: ---- - Used `tax_ids_after_fiscal_position` for tax calculation while computing the discount amount task-5421215 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256704 Forward-Port-Of: odoo/odoo#244650
This update resolves an issue where hidden fields within form blocks inside masonry layouts were still visible. The fix involves applying '!'important' to the CSS rule that hides these fields, ensuring they are consistently hidden as intended. This improves the visual consistency of the website editor.
Original PR description
# How to reproduce - Go to the website editor - Add a Masonry block - Add a Form inner block in the Masonry block - Select any fields of the form - Set it's visibility to Hidden - Save # The problem…
# How to reproduce - Go to the website editor - Add a Masonry block - Add a Form inner block in the Masonry block - Select any fields of the form - Set it's visibility to Hidden - Save # The problem The field is still visible. # Cause When a field has its visibility set to hidden, it is applied the `.s_website_form_field_hidden` CSS class which applies `display: none`. https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/website/static/src/snippets/s_website_form/001.scss#L26-L28 But that CSS rule is overriden by the masonry's `.s_masonry_block[data-vcss='001'] .row > div` CSS class. https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/website/static/src/snippets/s_masonry_block/001.scss#L1-L3 https://github.com/odoo/odoo/blob/995629db3231de944710751c3184bf1b8b1355c7/addons/website/static/src/scss/website.scss#L3246 # Proposed solution We set `display: none` with `!important` to prevent it from being overidden. We also need to add `!important` to its edit mode counter-part so that the field is still visible in that mode. opw-6038955 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256100
This update fixes an error in how alternative purchase orders are calculated. When using 'Purchase Alternatives,' the system was incorrectly generating a total price of $1360 instead of the expected $1500. The fix ensures accurate price calculations by correctly applying taxes and vendor prices within alternative POs.
Original PR description
[FIX] purchase: set the correct price in alternative PO Steps to reproduce the bug: - Enable "Purchase Alternatives" in settings - Go to Accounting > Configuration > Taxes: - Configure a 15% purchase…
[FIX] purchase: set the correct price in alternative PO
Steps to reproduce the bug:
- Enable "Purchase Alternatives" in settings
- Go to Accounting > Configuration > Taxes:
- Configure a 15% purchase tax:
- Advanced Options tab:
- Included in Price: enabled
- Create a storable product "P1":
- Tax: 15%
- In the Purchase tab, add vendors:
- "Azure Interior": price = $10, min qty = 1
- "Deco Addict": price = $15, min qty = 1
- Create a purchase order for "Azure Interior":
- Order 100 units → total price is automatically computed as $1000
- Create an alternative purchase order:
- Vendor: "Deco Addict"
- Copy products: enabled
Problem:
The price is $1360, instead of $1500
When the alternative purchase order is created and the product is set
on the purchase order line, the required onchange methods are not
triggered:
https://github.com/odoo/odoo/blob/ad253ef4c2cb06536b99bb919a3e01ed980d2e96/addons/purchase/models/purchase.py#L1169
As a result, both the unit price and the taxes are missing on the
purchase order line. When `_compute_price_unit_and_date_planned_and_name`
is triggered, it attempts to compute the `price_unit`.
https://github.com/odoo/odoo/blob/fb24ad03fc47a303fa8719c0795e1afa9a7eb821/addons/purchase/models/purchase_order_line.py#L345-L346
At this point, it checks whether the purchase order has a vendor.
Since "Deco Addict" is set, it calls `_fix_tax_included_price_company`
using:
- the supplier price ($15)
- the supplier tax (15%)
However, since no taxes are yet set on the purchase order line,
`_fix_tax_included_price_company` incorrectly assumes the price is
tax-included and converts it to a tax-excluded price
(~13.04 instead of 15).
https://github.com/odoo/odoo/blob/7076b4f4d0d933d93b24e8e4c7cf21ef0b0008e5/addons/account/models/account_tax.py#L571-L573
Then, a 15% tax is applied on top of this incorrect base price, leading
to the wrong total.
opw-6047004
Forward-Port-Of: odoo/odoo#258154This update ensures that attachments uploaded to cloud storage retain their original file type (mimetype). Previously, the system was incorrectly guessing the mimetype, which could lead to issues with how files were handled. This fix improves the reliability of cloud storage uploads and prevents potential data inconsistencies.
Original PR description
When uploading an attachment to cloud storage via `_post_add_create(cloud_storage=True)`, the attachment's original `mimetype` is guessed even if we specify it. With this commit we explicitly preserve given mimetype Discovered during task-5153790 Forward-Port-Of: odoo/odoo#257979
This update corrects a previous issue where delivery slip prices were incorrectly displayed in the company currency instead of the customer's order currency. This change ensures that commercial invoices and delivery documents accurately reflect the price paid in the order's currency, improving financial reporting and customer invoicing. The fix was triggered by a recent code update.
Original PR description
The product value reported on delivery slips may incorrectly use the company currency instead of the order currency. Steps to reproduce: - Enable multi-currency and create a foreign currency - Create a pricelist in the foreign currency - Create and confirm a Sale Order using that pricelist - Add a delivery via carrier (eg. Fedex) - Confirm the delivery and generate the commercial invoice. Issue: The 'sale_price' on the stock move lines is taken in company currency rather than order currency. opw-6104130 Forward-Port-Of: odoo/odoo#259020 Forward-Port-Of: odoo/odoo#258875
This update resolves an issue where QR codes generated for Swiss bank payments were being rejected. The problem stemmed from unauthorized Unicode characters within the QR code data. The fix ensures that only a specific, approved set of characters (324) are used, aligning with Swiss banking requirements and preventing payment rejections.
Original PR description
**Description of the issue/feature this PR addresses:** QR code is rejected by the bank, when it contains an invalid character `U+202F`. **Current behavior before PR:** Unauthorized Unicode characters are encoded in the QR-Bill, and it is rejected on the receiving part. **Desired behavior after PR is merged:** Any Unicode codepoint which is not in the subset of 324 allowed codepoints has to be filtered out. > spec of QR-bill allows only a subset of characters, a precise list of 324 Unicode codepoints (section 4.1.1, page 30 of the Swiss Implementation Guidelines for the QR-bill) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257961 Forward-Port-Of: odoo/odoo#254980
13 changes
Resolved issues and error corrections
This update fixes a discrepancy in the 'To Pay' dashboard metrics by including receipts alongside invoices and refunds. Previously, the dashboard didn't accurately reflect the total amount to pay due to missing receipt data. This ensures the dashboard numbers align with the detailed records available in the action view.
Original PR description
- The "To Pay" section in the purchase/sales dashboard was only considering invoices(`in_invoice` and out_invoice) and refunds(`in_refund` and `out_refund`) when computing the number and amounts to pay. - However, the corresponding action view includes receipts (`in_receipt` and `out_receipt`), leading to an inconsistency where the dashboard count and amount did not match the records shown after clicking. - This commit updates the dashboard query to also include receipts, ensuring consistency between the displayed metrics of the coreesponding purchase/sales dashboard and the action view. Related PR: https://github.com/odoo/enterprise/pull/111142 taskID-6040828
This update fixes an issue preventing Odoo from correctly processing German hybrid-style invoices through the Peppol exchange. The change ensures the 'zugferd' format is handled correctly, aligning it with the 'facturx' format and resolving a potential processing failure. This improves the accuracy of invoice data exchange.
Original PR description
The 'zugferd' key was missing from the `_get_customization_ids` mapping, causing potential failures when attempting to identify the correct CustomizationID for German hybrid-style invoices being processed through the Peppol exchange. This is because the 'zugferd' format was wrongly considered as peppol edi format, whereas it should behave like the 'facturx' format and be excluded from the peppol edi formats. opw-6009214 Forward-Port-Of: odoo/odoo#256696
This update ensures that tax amounts are accurately calculated when users group lines on an invoice. Previously, discrepancies in tax could occur. The changes also streamline the process by removing a redundant context key and updating a key test case to reflect Belgian tax regulations.
Original PR description
[FIX] account_edi_ubl_cii: correct tax amount when grouping lines When the user group lines of a move, the tax amount is now corrected if there's a difference in the tax amount before and after grouping This commit also removes the `ungroup_lines` context key, as the flow was changed in odoo/odoo#252458 Reword the `test_import_and_group_lines_by_tax` test: use belgian company and belgian taxes task-5993555 Forward-Port-Of: odoo/odoo#252719
This update fixes a technical issue preventing the correct calculation of the REAGYP deductible amount for Spanish farmers filing their SII tax returns. The update ensures that the compensation amount (ImporteCompensacionREAGYP) is now included in the total deductible quota, ensuring accurate reporting to the Spanish tax authority (AEAT).
Original PR description
Currently, the deducible amount for REAGYP is not passing through to the AEAT. This happens because the REAGYP compensation amount (ImporteCompensacionREAGYP) was missing from the total deductible quota calculation in the SII JSON payload. To fix this, we add 'sujeto_agricultura' to the list that cheks if the tax value for l10n_es is in the list task-6072773 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256586
This update resolves an issue where Odoo prevented the posting of vendor bills with numbers that didn't follow a strict, sequential order. This was due to the system's hashing logic, which requires continuous numbering. Now, vendor bills from third parties with varying document numbers can be processed correctly.
Original PR description
**Steps to reproduce** Install modules l10n_ar and l10n_latam_invoice_document. Go to Accounting > Configuration > Journals and enable \"Lock Posted Entries with Hash\" on a Purchase journal that…
**Steps to reproduce** Install modules l10n_ar and l10n_latam_invoice_document. Go to Accounting > Configuration > Journals and enable \"Lock Posted Entries with Hash\" on a Purchase journal that uses LATAM documents. Create and post a vendor bill with a high document number (e.g., '00001-00009999'). Create another vendor bill with a lower document number (e.g., '00001-00000100') and try to post it. **Issue** Posting the second vendor bill fails with a UserError: \"This move could not be locked either because some move with the same sequence prefix has a higher number. You may need to resequence it.\" This happens because core Odoo hashing logic enforces a strict, continuous sequential numbering per journal and prefix. The _get_chain_info method identifies moves to be secured by searching for entries with a sequence number strictly greater than the last hashed move in that chain: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4091-L4145 When a vendor bill is entered with a lower number than an already hashed one, it is excluded from the search, triggering the no_document warning: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4140 And the subsequent UserError in _get_chains_to_hash: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4180-L4184 Similarly, jumps in vendor numbering trigger a gap warning: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4130 Causing the error at: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4185-L4188 Since vendor bills are issued by third parties, we do not control their sequence, and forcing them into a single continuous chain is functionally incorrect. opw-6076673
This update resolves an issue preventing the posting of vendor bills with non-sequential document numbers. The system previously enforced strict sequential numbering, causing errors when bills didn't follow this pattern. This change allows for more flexible vendor bill numbering, aligning with typical business practices.
Original PR description
**Steps to reproduce** Install modules l10n_ar and l10n_latam_invoice_document. Go to Accounting > Configuration > Journals and enable \"Lock Posted Entries with Hash\" on a Purchase journal that…
**Steps to reproduce** Install modules l10n_ar and l10n_latam_invoice_document. Go to Accounting > Configuration > Journals and enable \"Lock Posted Entries with Hash\" on a Purchase journal that uses LATAM documents. Create and post a vendor bill with a high document number (e.g., '00001-00009999'). Create another vendor bill with a lower document number (e.g., '00001-00000100') and try to post it. **Issue** Posting the second vendor bill fails with a UserError: \"This move could not be locked either because some move with the same sequence prefix has a higher number. You may need to resequence it.\" This happens because core Odoo hashing logic enforces a strict, continuous sequential numbering per journal and prefix. The _get_chain_info method identifies moves to be secured by searching for entries with a sequence number strictly greater than the last hashed move in that chain: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4091-L4145 When a vendor bill is entered with a lower number than an already hashed one, it is excluded from the search, triggering the no_document warning: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4140 And the subsequent UserError in _get_chains_to_hash: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4180-L4184 Similarly, jumps in vendor numbering trigger a gap warning: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4130 Causing the error at: https://github.com/odoo/odoo/blob/976c9778c038e821176fc3b273bf4ad58bdc4810/addons/account/models/account_move.py#L4185-L4188 Since vendor bills are issued by third parties, we do not control their sequence, and forcing them into a single continuous chain is functionally incorrect. opw-6076673
This update resolves a critical issue where upgrading Odoo servers caused instability and crashes for IoT integrations. The previous process failed to correctly update IoT images, leading to outdated versions. This fix ensures IoT devices always receive the latest Odoo image, improving stability and performance.
Original PR description
**Description of the issue/feature this PR addresses:** As soon as new Odoo versions are released, deploy iotbox-latest.zip could be unreliable and lead to crash the IoT integration. And right now,…
**Description of the issue/feature this PR addresses:**
As soon as new Odoo versions are released, deploy iotbox-latest.zip could be unreliable and lead to crash the IoT integration. And right now, the upgrade wasn't even working as the new image name convention doesn't match the 'iotboxv' string.
**Current behavior before PR:**
- When we upgrade the Odoo server to which the IoTs are connected, they automatically get the new code for that server, so drivers are aligned to that version but the image is still the former one.
- If we hit update in the IoT to have a proper image up to date with the current server version:
<img width="584" height="172" alt="image" src="https://github.com/user-attachments/assets/0881a8cc-e69c-4fc1-be31-71de42abcae9" />
```
2026-03-31 06:55:33,007 892 ERROR ? odoo.http: Exception during request handling.
Traceback (most recent call last):
File "/home/pi/odoo/odoo/http.py", line 2592, in __call__
response = request._serve_nodb()
^^^^^^^^^^^^^^^^^^^^^
File "/home/pi/odoo/odoo/http.py", line 2064, in _serve_nodb
response = self.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/pi/odoo/odoo/http.py", line 2297, in dispatch
return endpoint(**self.request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/pi/odoo/odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/pi/odoo/addons/hw_posbox_homepage/controllers/homepage.py", line 208, in get_version_info
'imageIsUpToDate': not bool(helpers.check_image()),
^^^^^^^^^^^^^^^^^^^^^
File "/home/pi/odoo/addons/hw_drivers/tools/helpers.py", line 242, in check_image
return {'major': version[0], 'minor': version[1]}
~~~~~~~^^^
IndexError: list index out of range
```
This code here can't simply match with the new naming convention, but we don't to break the compatibility anyway:
https://github.com/odoo/odoo/blob/38734e4bc7d841a30524a2bc17fc94c9a83b5aa0/addons/hw_drivers/tools/helpers.py#L225-L242
<img width="546" height="150" alt="image" src="https://github.com/user-attachments/assets/cb2c59f9-46ce-48c7-ad5a-cf5f1cbee062" />
**Desired behavior after PR is merged:**
We can update at least to last supported version for the connected server
(I've been conservative about the image version as the IoT code is so binded to the connected server code... Maybe a higher one is safe?)
cc @moduon MT-11428
opw-6084090
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update resolves a bug that caused tests to fail unpredictably when activities were canceled. The fix ensures the system correctly waits for canceled activities to disappear before allowing users to complete other tasks, improving the reliability of the activity management feature. This enhances the overall user experience.
Original PR description
Recent fix of activity cross-tab data sharing [1] added a new test to make sure the feature works as expected. This test may fail non-determinstically after "cancel" of an activity. The failure happens because while this activity has been canceled, the next step is to click on "mark as done" on the other activity, but due to not awaiting the removal of the cancelled activity, the "mark as done" button may mistakenly target the activity that has just been cancelled. This commit fixes the issue by awaiting that the cancelled activity has been removed from UI, so that the selector to click on "mark as done" button is necessarily on the other activity [1] https://github.com/odoo/odoo/pull/255785
This update fixes a potential issue where website tours could incorrectly proceed if the chat feature was temporarily empty. The change implements a more reliable check to ensure the tour only continues when the chat is definitively empty, improving the overall user experience. This ensures tours execute correctly and consistently.
Original PR description
The previous negative assertion could pass prematurely during fast tour execution. Switching to a specific text based assertion ensures the step only proceeds once the empty conversation is explicitly confirmed.
This update resolves an issue where the checkout process became unresponsive when using the l10n_br_avatax_sale module with the Express Checkout feature. The previous implementation was causing unnecessary external API calls, leading to errors and preventing users from completing their purchases. This fix removes the problematic call and ensures a smoother checkout experience.
Original PR description
Issue: --- The extra external_tax call introduced in odoo/enterprise#101579 is causing multiple issues: 1- It doesn't catch errors while `_get_and_set_external_taxes_on_eligible_records` easily raises errors, causing uncatch errors in `website_sale`. 2- Extra unnecessary external api call in non-express checkout methods which is not desirable. Steps to reproduce: --- 1- Install l10n_br_avatax_sale, website_sale 2- Using a public user, add a product to cart and got to checkout. 3- In the address form, use CPF identification type. Outcome: The confirm button is unresponsive. Cause: --- This is due to uncatch error raised by external tax call, while it was not necessary at this step of this flow to call external tax api. opw-6005767 Forward-Port-Of: odoo/odoo#256692
This update resolves a problem where Odoo invoices sent via Peppol were being rejected due to an incorrect calculation of the taxable amount. The fix ensures that the tax calculation is consistently applied across all tax categories, addressing a specific Peppol compliance requirement. This prevents invoice rejections and ensures smooth international transactions.
Original PR description
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with…
Steps to reproduce: 1. Create an invoice with a 0% tax (Exempt from VAT, category E) 2. Add two lines with 20% discount and fractional prices: - qty=4, price_unit=39.615 and qty=4 with price_unit=0.84 3. Send via Peppol 4. Peppol rejects with: [BR-E-08] VAT category taxable amount shall equal the sum of Invoice line net amounts The TaxableAmount recalculation in _ubl_get_tax_subtotal_node was only applied for tax category 'S' (Standard Rate). However, Peppol schematron has identical rules for all tax categories: BR-E-08 (Exempt), BR-Z-08 (Zero), BR-AE-08 (Reverse Charge), etc. When lines have discounts and fractional prices, the individually rounded LineExtensionAmount values can sum to a different total than the tax base_amount. This affects both rounding modes. For 'S' taxes this was already handled, but for 'E' (and others) it caused Peppol rejection. Remove the 'S'-only filter and match dynamically against the actual tax category code so the recalculation applies universally. opw-6093243
This update resolves an issue where managers without specific Time Off Officer permissions couldn't approve leave requests displayed in the Gantt view. The fix adjusts permission logic to allow designated leave managers to approve, validate, and refuse requests, streamlining the approval process for managers while maintaining existing security controls.
Original PR description
### Issue before this commit: A manager without the Time Off Officer access rights was unable to approve, validate, or refuse a leave request from the Time Off Gantt. Attempting to perform these…
### Issue before this commit: A manager without the Time Off Officer access rights was unable to approve, validate, or refuse a leave request from the Time Off Gantt. Attempting to perform these actions raised an access error on the leave_id field of the hr.leave.report.calendar model. ### Steps to reproduce the issue: 1. In employee app create a manager, go to settings tab and create also a user for the manager as Related User 2. Create also an employee setting in the Work Information tab the manager as Time Off 3. Go to Users and for the manager deselect rights for Time Off and Payroll 4. Set a contract for the created employee and allocate some Paid days to him 5. Create a Time Off request for the employee. 6. Switch to manager account 7. Go to Time Off -> Overview -> Gantt View and try to approve the request. 8. Error: _You do not have enough rights to access the fields "leave_id" on Time Off Calendar (hr.leave.report.calendar). Please contact your system administrator._ ### Cause of the issue: The action_approve, action_validate, and action_refuse methods on the hr.leave.report.calendar model relied on accessing the leave_id field, which is restricted to users belonging to the hr_holidays.group_hr_holidays_user group. As a result, managers without this group could not read the field, triggering an AccessError even though they were legitimately allowed to approve leaves as managers. Backporting this PR: https://github.com/odoo/odoo/pull/207675 ### Reason to introduce the fix: Allow managers to perform leave approval, validation, and refusal actions without granting them broader Time Off access rights. This fix extends the permission logic to ensure that the employee’s designated leave manager can execute these actions when the validation type allows it, while preserving the standard access restrictions for other users. opw-6023628 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where stock quantities were incorrectly displayed for one company when a purchase order was processed across multiple companies. Now, stock quantities are correctly restricted based on the product's assigned company, preventing errors and ensuring accurate reporting for each company's inventory. This improves data consistency and reliability.
Original PR description
**Purpose:** Since a stock.quant is a combination of the stock move lines of a product and a location, it should be restricted by the product's company. **Before this commit:** In a multi-company…
**Purpose:** Since a stock.quant is a combination of the stock move lines of a product and a location, it should be restricted by the product's company. **Before this commit:** In a multi-company environment. If a purchase order with product from company 1 is being confirmed, received, and validated when company 2 is being selected as the primary active company while company 1 is also checked. It will create a stock.quant that is searchable for company 2. However, it will raise an error when company 2 is trying to access it. **After this commit:** Even if the stock.quant is created when company 2 is the primary active company, it will not be searchable for company 2 since the product's company is company 1. **Steps to Reproduce on Runbot:** - Create a storable product exclusive to Company A - Create & validate a receipt for that product in Company A. - Switch to Company B -> Reporting > Locations > Remove all filters: The negative quant for the product in Partners/Vendors is visible. opw-6082330 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257211
7 changes
Resolved issues and error corrections
This update resolves an issue where tax wasn't correctly applied to sales orders when using fixed amount discounts. Previously, users had to manually set tax on discount products. Now, the system automatically considers tax from the discount product, ensuring accurate tax calculations for all discount scenarios.
Original PR description
Steps to reproduce: - Apply fixed amount discount on sales order. - Go to the discount product which got created and set tax for it. - Again apply fixed amount discount on sales order. Issue: If tax is set for fixed amount discount product, tax is not applied when discount is applied on sales order. Cause: User have to manually set the tax even if he has set tax for fixed amount discount. Fix: Consider the tax from discount product if there is any. opw-3935350 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where German hybrid invoices processed through Peppol were failing to correctly identify invoice customizations. The change clarifies how the 'zugferd' format is handled, ensuring it's treated as a distinct format from Peppol EDI, leading to accurate invoice processing.
Original PR description
The 'zugferd' key was missing from the `_get_customization_ids` mapping, causing potential failures when attempting to identify the correct CustomizationID for German hybrid-style invoices being processed through the Peppol exchange. This is because the 'zugferd' format was wrongly considered as peppol edi format, whereas it should behave like the 'facturx' format and be excluded from the peppol edi formats. opw-6009214
This update resolves an issue where a previous manager would continue to receive department messages after a new manager was assigned. Now, when a manager is reassigned, they are automatically unsubscribed from all department communications, ensuring a cleaner and more accurate notification system. This improves the user experience for both managers and department members.
Original PR description
…ager is assigned Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a technical issue where an old manager would continue to receive department messages after a new manager was assigned. The change ensures that users are only notified about relevant department communications, improving email efficiency and reducing potential confusion. This is a minor fix impacting the HR module.
Original PR description
…ager is assigned Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where a previous manager remained listed as a follower after a new manager was assigned. The change ensures that the old manager is automatically unsubscribed from the department, maintaining accurate follower lists and streamlining organizational updates. This improves data accuracy and reduces potential confusion.
Original PR description
Description of the issue/feature this PR addresses: old manager is still in followers after changing Current behavior before PR: old manager is still in followers after changing Desired behavior after PR is merged: old manager gets unsubscribed to the department --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where stock quantities were incorrectly displayed for a company when a purchase order was processed through another company in a multi-company environment. The change ensures stock quantities are restricted to the product's assigned company, preventing errors and improving data accuracy. This resolves a reporting discrepancy.
Original PR description
**Purpose:** Since a stock.quant is a combination of the stock move lines of a product and a location, it should be restricted by the product's company. **Before this commit:** In a multi-company…
**Purpose:** Since a stock.quant is a combination of the stock move lines of a product and a location, it should be restricted by the product's company. **Before this commit:** In a multi-company environment. If a purchase order with product from company 1 is being confirmed, received, and validated when company 2 is being selected as the primary active company while company 1 is also checked. It will create a stock.quant that is searchable for company 2. However, it will raise an error when company 2 is trying to access it. **After this commit:** Even if the stock.quant is created when company 2 is the primary active company, it will not be searchable for company 2 since the product's company is company 1. **Steps to Reproduce on Runbot:** - Create a storable product exclusive to Company A - Create & validate a receipt for that product in Company A. - Switch to Company B -> Reporting > Locations > Remove all filters: The negative quant for the product in Partners/Vendors is visible. opw-6082330 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures that invoices sent via email now use the custom 'Printed Report Name' configured for reports, rather than a default naming pattern. The change corrects a previous issue where invoice emails incorrectly generated attachments with generic names, leading to potential confusion and misidentification of documents. This improves the clarity and professionalism of invoice communications.
Original PR description
When sending an invoice by email template, the generated PDF attachment does not use the configured Printed Report Name. Instead, it falls back to a default naming pattern (e.g. report action name +…
When sending an invoice by email template, the generated PDF attachment does not use the configured Printed Report Name. Instead, it falls back to a default naming pattern (e.g. report action name + invoice number). This is due to a difference in flow: sales use the standard mail.compose.message wizard, which correctly applies each report’s print_report_name, while invoices use the dedicated account.move.send wizard. In the invoice flow, _get_placeholder_mail_template_dynamic_attachments_data uses the invoice report context instead of the actual dynamic report. To fix this, the send flow is updated so _get_placeholder_mail_template_dynamic_attachments_data computes the filename from extra_mail_template. Additionally, _get_invoice_report_filename needs to be extended in 17.0 to optionally accept a report and use its print_report_name like in the newer versions while preserving fallback behavior. The safe_eval is taken from code used in the future version's code, and is needed as the field accepts python expressions. This naming issue occurs from 17.0 to current master, and the fix will ensure extra dynamic reports follow their configured printed name. Steps to reproduce: Go to Settings > Technical > Reporting > Reports and duplicate the standard Invoice report. In the duplicated report, set a custom value in Printed Report Name (e.g. 'CUSTOM_NAME_TEST'). Go to Settings > Technical > Email > Templates and open “Invoice: Send my email”. Add the duplicated report under Dynamic Reports. Create a customer invoice and confirm it. Click Send (or Send & Print) to open the email preview. Related Ticket: opw-6058716