Daily updates from Odoo
Wednesday, March 25, 2026
18 changes · 18.0
Resolved issues and error corrections
This update resolves an issue where the AEAT tax report file was being rejected due to an incorrect date format. The fix ensures the file includes a default numeric date ('00000000') when the procuration date is not specified, meeting AEAT's requirements and allowing successful file uploads.
Original PR description
Steps to reproduce: - Install the `l10n_es_reports` module and switch to the `ES company`. - Go to Invoices and create an invoice with taxes, then confirm it. - Navigate to Accounting > Reporting >…
Steps to reproduce: - Install the `l10n_es_reports` module and switch to the `ES company`. - Go to Invoices and create an invoice with taxes, then confirm it. - Navigate to Accounting > Reporting > Tax Report. - From the smart button, select `Report: Tax Report (Mod 390) (ES)` and choose the year as `This Financial Year`. - Download the `BOE` file using the dropdown and fill the wizard fields (e.g., Natural Person – Name: Test, Principal activity: Test, Activity Code: 12345). - Upload the generated .txt file to the AEAT portal. (AEAT credentials are required) **Observation:** AEAT rejects the file with: `Caracteres no válidos '4. Representante - Personas Jurídicas - Represent. 1 - Fecha Poder (DDMMAAAA)'` **Root cause:** At [1], when `judicial_person_procuration_date` is `false`, an empty string is written to the BOE file, resulting in blank spaces in the exported file. This does not comply with AEAT’s required numeric format and causes the file to be rejected. **Fix:** This commit ensures the file contains '00000000' when `judicial_person_procuration_date` is false, complying with AEAT numeric format requirements. [1]: https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/l10n_es_reports/models/aeat_tax_reports.py#L1696 opw-5995290 Forward-Port-Of: odoo/enterprise#109652
This update corrects a problem where ISO20022 XML files generated for Swiss bank accounts in version 18.0 were being rejected by banks. The fix ensures the correct 'PAIN 09' format is used, resolving compatibility issues after database migration. This prevents delays in financial transactions.
Original PR description
To reproduce the issue:
- Create a database in 17.0, with a Swiss company, and install account_sepa. Make sure the bank journal uses the Swiss IS020022 PAIN version.
- Migrate this database to 18.0
- Generate an ISO20022 xml file for the Swiss company
==> The file is wrongly formatted, and will be rejected by the bank.
This happens because the sepa_pain_version field of the journal is still set to its old selection value ('pain.001.001.03.ch.02') after migration, which is not supported anymore. The ORM hence returns an empty value when accessing the selection field, and does not enter the proper conditions when generating the file.
An upgrade fix has been made here https://github.com/odoo/upgrade/pull/9771. This commit makes sure already-migrated databases dynamically fix the issue as well.
opw-6060612This update fixes an issue where quality control moves weren't correctly splitting stock when partial failures occurred. Specifically, the demand quantity was calculated incorrectly, leading to an inaccurate split of the affected stock. This ensures accurate stock management and reporting during quality control processes.
Original PR description
**Steps to reproduce:** * Install the `quality_control` module. * Create a storable product. * Configure a Quality Control Point: * Set Control per : Quantity. * Set Operation Type to Receipts. * Set…
**Steps to reproduce:** * Install the `quality_control` module. * Create a storable product. * Configure a Quality Control Point: * Set Control per : Quantity. * Set Operation Type to Receipts. * Set Product to the created product. * Create a Receipt for the product with a demand of 5 units. * Confirm the receipt and mark it as To Do. * Click on the Quality Check button. * Click on Fail and set the failed quantity to 3. * Click on Confirm. **Observed behavior:** * A new stock move is created for the failed quantity. * The original move is split incorrectly: * First move: 2 `product_uom_qty` and 2 `quantity`. * Second move: 2 `product_uom_qty` and 3 `quantity`. * The failed move has a demand of **2** instead of **3**. **Cause:** * Clicking on *Quality Check* triggers `check_quality`, which opens the wizard `action_open_quality_check_wizard`: https://github.com/odoo/enterprise/blob/90567af2703a3928c35814a0c4862b4cd98b8432/quality_control/models/stock_picking.py#L79-L82 * Clicking on *Fail* triggers `do_fail`, opening the confirmation wizard: https://github.com/odoo/enterprise/blob/90567af2703a3928c35814a0c4862b4cd98b8432/quality_control/wizard/quality_check_wizard.py#L85-L88 * Clicking on *Confirm* triggers `confirm_fail`, which calls `_move_line_to_failure_location`: https://github.com/odoo/enterprise/blob/90567af2703a3928c35814a0c4862b4cd98b8432/quality_control/wizard/quality_check_wizard.py#L97 * In `_move_line_to_failure_location`, a new stock move is created for the failed quantity: https://github.com/odoo/enterprise/blob/90567af2703a3928c35814a0c4862b4cd98b8432/quality_control/models/quality.py#L480 * The demand quantity is computed using the minimum of the failed quantity and the move line quantity. * This leads to an incorrect demand of *2* instead of *3*. * However, the move line quantity was already reduced by the failed quantity: https://github.com/odoo/enterprise/blob/90567af2703a3928c35814a0c4862b4cd98b8432/quality_control/models/quality.py#L472 **Fix:** * Ensure that partial failures properly split stock moves with correct `product_uom_qty` and `quantity` values. --- opw-5492095
This update fixes an issue where the barcode scanner was incorrectly using the user's company instead of the current business context. This resulted in incorrect barcode recognition, preventing users from scanning products correctly. The fix ensures the scanner utilizes the appropriate company information for accurate barcode processing.
Original PR description
### Issue: The company used in the main barcode menu is the `company_id` of the user rather than the current contextual company of the session. This is problematic as we might endup using the wrong…
### Issue: The company used in the main barcode menu is the `company_id` of the user rather than the current contextual company of the session. This is problematic as we might endup using the wrong barcode nomenclature. ### Steps to reproduce: - Have 2 companies: company 1 and company 2 - Set the barcode nomenclature of company 1: default, company 2: GS1 - Incarnate a user allowed in both companies but with default company 1 - With company 2, create a product and set its barcode to 36939282410106 - From the main menu open the barcode app and scan 0136939282410106 #### > No product was found (even thought it is correct in GS1) ### Cause of the issue: Scanning from the main barcode menu will trigger a call of the `main_menu` method relying on the nomenclature of the contextual company of the request: https://github.com/odoo/enterprise/blob/804ea21c225a7a1e0763bac188f027adeb3ab78f/stock_barcode/static/src/main_menu/main_menu.js#L98-L99 https://github.com/odoo/enterprise/blob/804ea21c225a7a1e0763bac188f027adeb3ab78f/stock_barcode/controllers/stock_barcode.py#L15-L21 However, when opening the main barcode menu from the app menu, no contextual warehouse was set to the view: https://github.com/odoo/enterprise/blob/804ea21c225a7a1e0763bac188f027adeb3ab78f/stock_barcode/views/stock_barcode_views.xml#L6-L11 As such, the environment of the request will be set here: https://github.com/odoo/odoo/blob/9393b0db6791fe5a7f576cff55705e315fb3dd11/odoo/http.py#L2083 based on the company of the user rather than the one of the context: https://github.com/odoo/odoo/blob/9393b0db6791fe5a7f576cff55705e315fb3dd11/odoo/api.py#L694-L722 ### Fix: Setting the company slices the `current_company` in first position of the `allowed_company_ids`: https://github.com/odoo/odoo/blob/260c69ed64f8663b6935b9863c86aac6dbecd961/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js#L33-L39 https://github.com/odoo/odoo/blob/260c69ed64f8663b6935b9863c86aac6dbecd961/addons/web/static/src/webclient/switch_company_menu/switch_company_menu.js#L68-L81 which can be recovered from the cookies via the `_get_allowed_company_ids`: https://github.com/odoo/enterprise/blob/43f65ff2f3c6177cc69647bbb85bb40a84409457/stock_barcode/controllers/stock_barcode.py#L432-L442 precisely used by the `_get_barcode_nomenclature`: https://github.com/odoo/enterprise/blob/43f65ff2f3c6177cc69647bbb85bb40a84409457/stock_barcode/controllers/stock_barcode.py#L485-L491 Note that passing the context in the arguments of the `main_menu` JSON route will not really solve the issue by it self since the context is no longer shared with the request: c8cd1d4a83de7a5798cbb910a788fbb6fe208d2f ### Additional Issue: The type `dest_location` does not exist on barcode types: https://github.com/odoo/odoo/blob/485a64b6a1e91feb4310f282c6dd1cd021f1780b/addons/barcodes_gs1_nomenclature/models/barcode_rule.py#L16-L20 so that the type used by these lines can not work: https://github.com/odoo/enterprise/blob/1dedc5bbcee43bfd13e55206e3d7364f715ca9be/stock_barcode/controllers/stock_barcode.py#L29-L30 https://github.com/odoo/enterprise/blob/1dedc5bbcee43bfd13e55206e3d7364f715ca9be/stock_barcode/controllers/stock_barcode.py#L52-L56 ### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set the barcode nomenclature to GS1 - Set your warehouse in receipt in two steps and add a barcode to the WH/Input: 3033710074365 - From the main menu open the barcode app and scan 4133033710074365 #### > No product or picking was found (even thought it is correct in GS1 that should create an internal transfer with WH/INPUT as destination) opw-5847529
This update resolves an issue where the POS scale integration was not accurately displaying product weights due to a change in how the IoT box sends scale data. The fix ensures that the POS correctly reads and displays weight measurements from the physical scale, improving the accuracy of product tracking. This update is critical for accurate inventory management within the POS system.
Original PR description
Steps to reproduce - Use a localisation other than a european one (l10n_eu_iot_scale_cert must not be installed) - Setup the scale for the POS - Open the POS - Add a product to be weighted by scale to the order - Add product to the physical scale - The displayed weight is always 0 Cause: New versions of the IoT box uses the field result to return the scale measure instead of value. Fix for version 18.0 and its intermediary versions. [opw-5990467](https://www.odoo.com/odoo/project/49/tasks/5990467)
This update resolves an issue where discounts weren't correctly processed in the self-order point-of-sale flow. The fix ensures that discount information is properly handled, preventing errors and guaranteeing accurate pricing calculations during self-order transactions. This improves the reliability of the self-order experience.
Original PR description
In the pos self-order flow, `_check_pos_order_lines` does not forward the `discount` field when sanitizing order lines. This caused `_merge_order_lines` to raise a `KeyError` when using `itemgetter('discount')` on lines that lack the key.
opw-6052719This update fixes an issue where global invoices generated from customer invoices weren't correctly using the issued address's zip code in the XML export. The change ensures that the correct postal code is included, improving compliance with Mexican tax regulations. This resolves a reported problem (opw-5956837) related to invoice data accuracy.
Original PR description
**STEP TO REPRODUCE** 1. install l10n_mx_edi_extended. 2. Add an issued address on the customer invoice journal, with a zip code. 3. Create invoices, and create a global invoice with them. 4. download the xml, and notice the field LugarExpedicion is not using the zip from the issued address while it should. opw-5956837
This update prevents 404 errors when accessing public website content without logging in. The issue stemmed from a delay in website context availability during access rule evaluations, leading to incorrect access denials. The fix ensures website context is correctly established, granting access to public records as intended.
Original PR description
\* = test_website_modules ### Issue: When accessing a record from the website without logging in, a `404` error occurs if a public record rule filters records by website related domain, for example…
\* = test_website_modules
### Issue:
When accessing a record from the website without logging in, a `404`
error occurs if a public record rule filters records by website related
domain, for example `[('website_id', '=', website.id)]`.
### Steps to reproduce:
- Install the 'website_blog' module and create at least one website.
- Enable debug mode.
- Go to Settings > Technical > Database Structure > Models.
- Open the `blog.post` model.
- Go to the 'Record Rules' tab.
- For the record 'Blog Post: public: published only', change the domain
from `[('website_published', '=', True)]` to
`[('website_id', '=', website.id)]`.
- Go to Website > Configuration > Blogs.
- Open a blog (e.g., Travel).
- Select 'My Website' in its 'Website' field.
- Open 'My Website' without logging in.
- Click on the 'Blog' menu and the blog listing will appear correctly.
- Try opening a blog post and a `404` error occurs.
### Reason:
<pre>
┌─────────────────────────────────────────────────────────┐
│ Request Lifecycle │
├─────────────────────────────────────────────────────────┤
│ │
│ User Request (not logged in) │
│ ↓ │
│ ┌──────────────────────────────────────┐ │
│ │ 1. _pre_dispatch │ │
│ │ ↓ │ │
│ │ check_access_rule │ │
│ │ ↓ │ │
│ │ _eval_context (compute domain) │ │
│ │ ↓ │ │
│ │ get_request_website() │ │
│ │ ↓ │ │
│ │ request.website = None │ ← Issue │
│ │ ↓ │ │
│ │ Domain evaluation FAILS │ │
│ │ ↓ │ │
│ │ Access DENIED → 404 Error │ │
│ └──────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────┐ │
│ │ 2. _frontend_pre_dispatch │ │
│ │ (NEVER REACHED) │ │
│ │ ↓ │ │
│ │ request.website initialized ✓ │ ← Too Late │
│ └──────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
</pre>
Because `request.website` is initialized later in
`_frontend_pre_dispatch`, access rules evaluated earlier in
`_pre_dispatch` cannot rely on website context. As a result, record
rules depending on `website_id` are evaluated before `request.website`
is available, incorrectly denying access to public records.
### Fix:
Avoid totally relying on `get_request_website` during access rule
evaluation. Use the `request.is_frontend` attribute as a fallback, which
is set earlier, to detect frontend requests and ensure correct access
handling.
task-[4758311](https://www.odoo.com/odoo/project/974/tasks/4758311)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#213143This update fixes a bug in the export data dialog that prevented users from accurately searching for items using display names like 'Order Lines/Product'. The fix reverses the search pattern to correctly match these names, ensuring data is exported as expected. Technical IDs continue to function correctly for debugging.
Original PR description
The export dialog reverses field.string to prioritize field names over parent paths
in fuzzy search scoring. However, the search pattern was not reversed, causing
mismatches when searching with display names like "Order Lines/Product".
Before: pattern "Order Lines/Product" searched in reversed string "Product/Order Lines"
→ character order mismatch → no results
After: both pattern and string are reversed → proper matching
This fix ensures searching by display names (e.g., "Order Lines/Product") works
as expected, while technical IDs (e.g., "order_line/product_id") continue to work
in debug mode.
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#234267This update resolves an issue where invoices with 'division' tax types were incorrectly formatted, leading to rejection by the JoFotara system. The fix ensures that the necessary tax percentage information is included in the invoice XML, preventing errors and ensuring proper processing of invoices.
Original PR description
Taxes with `amount_type == 'division'` were treated as non-percentage types, causing `cbc:Percent` to be omitted from the generated XML and `TaxScheme/ID` to be set to `OTH` instead of `VAT`. JoFotara rejects invoices where `cbc:Percent` is absent, raising a NullPointerException on the receiver side. opw-5919123 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a potential inconsistency in point-of-sale tax settings. Previously, users could modify tax inclusion while a POS session was open, leading to discrepancies between receipts and invoices. The change now prevents these modifications, ensuring accurate financial reporting.
Original PR description
There is a safeguard in account.tax.write prevents modifying taxes as it is forbidden to modify a tax used in a POS order not posted. This guard only applies for a predefined set of fields in account_tax.py. After 18.0, the tax-included behavior is controlled through the `price_include_override` field instead of `price_include`. However, this field was not added in the forbidden fields, allowing users to modify tax inclusion while a POS session is open. This bypasses the safeguard and can lead to inconsistencies, as the POS caches tax configuration at session start. For example, changing this setting mid-session may differences between POS receipts and backend invoices. By adding `price_include_override` to the forbidden fields, the UserError can properly be raised. Additional note: test_fiscal_position_between_frontend_and_backend was updated to close the POS session before changing taxes since the safeguard now correctly blocks this. Related ticket: opw-6042367
This fix resolves an issue where merging tables in the Point of Sale system incorrectly calculated product quantities, leading to inaccurate order displays. The update ensures that quantities are calculated correctly when merging tables, preventing incorrect order totals and improving the user experience.
Original PR description
**Steps to reproduce:** - Go to PoS restaurant - Enter a table 1, click on 2 Food products but don't order them - Go to another table 2, click 4 Food products and order them - Merge table 2 into…
**Steps to reproduce:** - Go to PoS restaurant - Enter a table 1, click on 2 Food products but don't order them - Go to another table 2, click 4 Food products and order them - Merge table 2 into table 1 - First issue, the quantity to be ordered is -2 (2-4) instead of 2 - Click on the order button - It now shows 4, but doesn't do anything in the kitchen display when clicked **Why the fix** When merging 2 tables, the products from the starting table were taken into account in the categories count, and the were counted as negatives. This is why in the example above, we see -2, because we have 4 products incoming, meaning we take the 2 current products on the destination table and subtract the 4 incoming ones. We now set the correct line uuid on the new table's last_order_preparation_change so that they can later be ignored in **getOrderChanges**. The problem was that when transfering an order, we got the old preparation line from the *last_order_preparation_changes*, and added it to the new order's *last_order_preparation_change*. But we created a new line in the new order, so the uuid would not match and would then later be ignored in this code, which would result in them being counted again as not sent to the kitchen. https://github.com/odoo/odoo/blob/80b602f2fa82366280f9beaa3414c27293bdc4f6/addons/point_of_sale/static/src/app/models/utils/order_change.js#L43 https://github.com/odoo/odoo/blob/80b602f2fa82366280f9beaa3414c27293bdc4f6/addons/point_of_sale/static/src/app/models/utils/order_change.js#L66-L68 As we didn't have the transferred lines in oldChanges anymore, we took the quantity, instead of the quantity - the quantity from the already ordered in the old table, so this is why the button was still clickable and still displayed some quantity even right after it was clicked. With this commit, the transferred lines are now counted in *last_order_preparation_change*, so they are not counted again in the number of products to send to the kitchen. opw-6008174
This update fixes an issue where invoice quantities were incorrectly calculated when using timesheets. The system was adding timesheet hours directly to the invoice line instead of converting them to the Sale Order Line's unit of measure (Days). This change ensures that invoice quantities accurately reflect the actual time worked, improving billing accuracy.
Original PR description
Steps to reproduce: -------------------------- 1. Install sale_timesheet 2. Create a quotation with a timesheet-based product - Set quantity = 3 - Set UoM to Days (timesheet UoM is Hours) 3. Confirm…
Steps to reproduce: -------------------------- 1. Install sale_timesheet 2. Create a quotation with a timesheet-based product - Set quantity = 3 - Set UoM to Days (timesheet UoM is Hours) 3. Confirm the quotation and click on the smart button Recorded. 4. Record 16 hours of timesheets. 5. Create an invoice using a timesheet period (starting from SO date) 6. Check the invoice quantity Issue: ----------- The invoice quantity is incorrect. It assigns the hour value (e.g., 16) to the invoice line even though the SOL is configured in "Days" (expected 2 days for 16 hours). Cause: ----------- After this commit c3b6053, The `_recompute_qty_to_invoice` method sums timesheet `unit_amount` (in hours) and assigns it directly to `qty_to_invoice` without converting it to the sale order line UoM when a timesheet period is applied. Solution: --------------- Convert the aggregated timesheet hours into the SOL UoM before assigning it to qty_to_invoice. opw-6024804 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures the 'send by Peppol' option in the Odoo send wizard is only available for companies that are actually registered on the Peppol network. Previously, it was incorrectly enabled, leading to potential confusion. This change improves data accuracy and aligns with registration requirements.
Original PR description
Previously, the send wizard would automatically enable the send "by Peppol" option whenever Peppol was available for the company's country. This behavior was misleading, as it didn't check whether the company was actually registered on Peppol. This commit ensures the option is only enabled for companies that are registered on Peppol. task-6044073 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where the expiration date on stock moves wasn't correctly updated when switching between lots. Now, the expiration date is accurately calculated and reset when changing lots, ensuring accurate inventory tracking and preventing potential stock discrepancies. This improves the reliability of our expiration date management feature.
Original PR description
Steps to reproduce: - Enable "Expiration Dates" in Inventory settings - Create a storable product "P1" - Add 10 units with "Lot 1" - Enable expiration dates on product P1 - Add 10 units with "Lot 2"…
Steps to reproduce: - Enable "Expiration Dates" in Inventory settings - Create a storable product "P1" - Add 10 units with "Lot 1" - Enable expiration dates on product P1 - Add 10 units with "Lot 2" and set an expiration date - Create a delivery for 10 units of P1 - Mark as "To Do" - Open the move line -> "Lot 1" is automatically reserved - Change the lot from "Lot 1" to "Lot 2" -> The expiration date is not updated automatically - Save and reopen the move line -> The expiration date is correctly set - Change again to "Lot 1" - Save and reopen the move line -> The expiration date is not reset and incorrectly keeps the value from "Lot 2" Cause: The expiration date was only computed based on `lot_id`, ignoring the `quant_id` used during reservation. Additionally, the value was not reset when switching to a lot without an expiration date. Solution: - Add `quant_id` to the compute dependencies - Compute the expiration date based on `quant_id.lot_id` - Explicitly set an expiration date to today when the use_expiration_date product is set to True and the lot doesn't have an expiration date. Result: The expiration date is now correctly updated and cleared when changing lots on stock move lines. opw-5999294
This update corrects a reporting issue where sale order lines on archived projects were incorrectly included in project revenue calculations. Previously, this led to inaccurate revenue reporting, making it difficult to understand project performance. Now, archived tasks and their associated sales are excluded from the dashboard's revenue figures.
Original PR description
Archived tasks are hidden by default. However, sale order lines on archived tasks are still included in the project dashboard display. Video example: https://drive.google.com/file/d/1FMG-eEuyO5cJS0UwHpdIwBaVUMUCyGUt/view?usp=sharing This can make it difficult to determine where the excess revenue is coming from. This commit ensures that sale order lines set on archived tasks are ignored in the dashboard's revenue calculations. opw-5922894 Link to ticket: https://www.odoo.com/odoo/project.task/5922894 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where Field Service Reports generated for multiple tasks would sometimes create duplicate PDFs. The fix addresses a technical problem related to how the system handles report generation and merging of streams, ensuring that reports are generated correctly and consistently.
Original PR description
### Issue: When we try to print the field service report on multiple tasks, some with worksheets, then everything is duplicated in the PDF. ### Steps to reproduce: - Install `industry_fsm` and `sale`…
### Issue: When we try to print the field service report on multiple tasks, some with worksheets, then everything is duplicated in the PDF. ### Steps to reproduce: - Install `industry_fsm` and `sale` - Create two tasks with the same customer - Add timesheet, products and save a worksheet on one of them (the goal is to have titles on two different pages) - In list view select both tasks and click Report > Field Service Report - The downloaded PDF has the report twice ### Cause: When printing for several records then `_render_qweb_pdf_prepare_streams()` tries to split the document. If the document has more pages than the number of records [we fetch the "Outlines"](https://github.com/odoo/odoo/blob/55a58571fbfa6a6bb0edacd6f9676382cc23630b/odoo/addons/base/models/ir_actions_report.py#L938-L954). These are the biggest sections in the document. In our case these sections are the `<h2>` tags, as there are no `<h1>`: [the main title](https://github.com/odoo/enterprise/blob/6c4b88a1dfe245a63a424e3f51ff803e51ccde61/industry_fsm/report/worksheet_custom_report_templates.xml#L31-L33), [the Timesheet section title](https://github.com/odoo/enterprise/blob/6c4b88a1dfe245a63a424e3f51ff803e51ccde61/industry_fsm/report/worksheet_custom_report_templates.xml#L39), etc. Then we check the pages where these titles are displayed; if we get the same number of pages as the number of records, we use them to split the report. If not, then we [render the report for each record individually](https://github.com/odoo/odoo/blob/55a58571fbfa6a6bb0edacd6f9676382cc23630b/odoo/addons/base/models/ir_actions_report.py#L974-L976), add them to `collected_streams`. Then add the initial report generated on the recordset and return. These streams are later merged into one, which explains the duplication: - Task 1 report individually generated - Task 2 report individually generated - Report of the recordset containing the two first reports ### Solution: The issue was introduced by [this commit](https://github.com/odoo/odoo/commit/7fc1ebd4466a2d9b4a48dfe86332b5844026c4fc) which implements the individual generation without returning. So the individual documents will always be followed by the recordset document. This commit adds the return directly after the individual reports generation. opw-6032935
This update ensures that stock valuation calculations, specifically the total value displayed for products, are consistent across Odoo versions (v18 and v19). The change corrects a previous issue where only internal locations were considered, leading to different total values after database migration. This update guarantees accurate inventory valuation.
Original PR description
**Steps to reproduce** - Create a database in v18.0. - Install the stock and sale modules. - Create a storable product. - Add 100 units as on-hand quantity using an inventory adjustment in the…
**Steps to reproduce** - Create a database in v18.0. - Install the stock and sale modules. - Create a storable product. - Add 100 units as on-hand quantity using an inventory adjustment in the internal location (e.g., WH/Stock). - Create a transit location. - Create an internal transfer and move 20 units from the internal location (WH/Stock) to the Transit location. - WH/Stock now contains 80 quantities. - Transit location contains 20 quantities. - See stock valuation of product. **Issue** - In v18, `value_svl` and `quantity_svl` are computed from [Stock Valuation Layers](https://github.com/odoo/odoo/blob/18.0/addons/stock_account/models/product.py#L213) After that, `total_value` is calculated using the formula [`avg_cost * qty_available`](https://github.com/odoo/odoo/blob/18.0/addons/stock_account/models/product.py#L205). However, when calling `qty_available`, no location context is passed to specify which locations should be considered. Because of this, `qty_available` only considers quantities from internal locations. As a result, the final `total_value` is computed based only on the internal location quantity (80). - When the customer migrates the database to v19, the displayed `total_value` changes. In v19, both (100 qty) internal and transit locations are considered when computing the quantity used for valuation. This happens because a valuation [context](https://github.com/odoo/odoo/blob/19.0/addons/stock_account/models/product.py#L203) is passed when selecting the locations for the quantity computation. Due to this change, the quantity used in the calculation includes both internal and transit locations, which can lead to a different `total_value` being displayed compared to v18. **Solution** - To resolve this issue, the valuation context has been passed when computing the value in the function. This context includes both internal and transit locations. As a result, when `qty_available` is computed, it considers these locations, and the resulting `total_value` remains consistent with the valuation logic. opw-5924110 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr