Wednesday, April 15, 2026
27 changes · 19.0
Resolved issues and error corrections
Invoices now only suggest outstanding payments or credit notes from the same company as the invoice. This prevents users in multi-company setups from trying to apply payments from another company, avoiding confusing validation errors and improving day-to-day accounting workflows.
Original PR description
The invoice outstanding credits/debits widget currently displays all reconcilable items for a partner across the same account, regardless of the company they belong to. In multi-company environments,…
The invoice outstanding credits/debits widget currently displays all reconcilable items for a partner across the same account, regardless of the company they belong to. In multi-company environments, specifically when accounts have been merged, this allows users to see and try to reconcile payments from Company A into an invoice from Company B. This action eventually triggers a validation error stating that entries must belong to the same company. This commit adds a company filter to the widget's logic to ensure only relevant outstanding payments are suggested, preventing cross-company reconciliation errors and improving UX. **Description of the issue/feature this PR addresses:** This PR fixes a validation error in multi-company environments where the invoice_outstanding_credits_debits_widget suggests payments or credit notes belonging to a different company than the current invoice. The issue typically arises when a partner has outstanding transactions in multiple companies and the accounts (e.g., Account Receivable) have been merged, allowing the widget to query lines that are not valid for the current record's company context. **Current behavior before PR:** When viewing an invoice for Company A, the "Outstanding Credits/Debits" widget displays all reconcilable account.move.line records for that partner that match the account type, regardless of their company_id. If a user clicks "Add" on a payment that belongs to Company B, Odoo attempts to reconcile them, resulting in a traceback or a validation error: "Invalid Operation: All tracebacks/entries must belong to the same company." This creates confusion for the end-user, as they are presented with "ghost" credits that cannot actually be applied. **Desired behavior after PR is merged:** The invoice_outstanding_credits_debits_widget (and the underlying logic in account.move) will strictly filter the suggested outstanding items by self.company_id. Users will only see and be able to reconcile payments, credit notes, or debits that belong to the same company as the invoice they are currently processing. This ensures data integrity and a seamless UX in multi-company setups. **Steps to reproduce:** Enable Multi-Company: Ensure you have at least two companies (e.g., Company A and Company B) active in your database. Chart of Accounts Setup: In both companies, use the same account for Receivables (or merge them so they share the same ID/Code if testing a migrated environment). Ensure the account is marked as Allow Reconciliation. Create a Payment in Company B: Post the payment so it remains as an "Outstanding Receipt". Create an Invoice in Company A Confirm/Post the invoice. Check the Widget: Scroll down to the bottom of the Invoice form in Company A. Observe the "Outstanding Credits" widget. The Error: The payment from Company B will appear as an available credit for the invoice in Company A. Click on "Add". A validation error (UserError) will pop up: "All entries must belong to the same company." **video** https://drive.google.com/file/d/1PfBxupP8t-t21wsP2FIgNXFnTP0Zq140/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Kit component costs are now calculated using matching units of measure, such as converting grams to kilograms before applying a per-kilogram price. This prevents large pricing errors in manufacturing kits and improves the accuracy of inventory and accounting values.
Original PR description
When computing the kit price unit, the component quantity from bom.explode() is expressed in the BOM line's UOM (e.g. grams), while price_unit is in the product's standard UOM (e.g. kg). Without conversion, a component at 430/kg with 400g in the BOM would yield 430 * 400 = 172000 instead of 172. Fix by converting the BOM line quantity to the product's UOM using _compute_quantity before accumulating into component_qty_per_kit. opw-6111342 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale now converts product prices from each product's own currency into the currency configured for the PoS. This prevents incorrect prices when businesses sell products priced in currencies different from the company currency.
Original PR description
Before this commit, in a multi-currency environment, the company currency was used to convert the prices, while it was a wrong assumption that the product prices were in the company currency. The products have a currency_id field, and the price should be converted from that currency to the PoS config currency. opw-6065969 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This pull request fixes several user-facing issues across Odoo, including clearer snailmail errors, prevention of duplicate POS stock transfers, more accurate timesheet dashboard filters, and safer Peppol invoice journal settings. It also improves invoice address display for German localization and resolves smaller reliability issues in projects, accounting localization, and browser subprocess cleanup.
Original PR description
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
Imported electronic invoices now choose the matching tax for the partner’s country when multiple taxes share the same rate and type. This prevents invoices from applying an incorrect tax from another country, improving accounting accuracy for multi-country setups.
Original PR description
When retrieving a tax from a document it would take the first tax that matches the amount/type/usage without taking the country into account. So if you have 2 taxes with the same amount/type/usage but different countries it would take the one with the lowest id which could lead to wrong tax being applied. Steps to reproduce: ------------------- * You can use the XML in the ticket to reproduce the issue. * Create a Belgian company. * Create a copy of the 21% purchase tax from Belgium and set the country to anything else. * Make sure that the newly created tax has a lower sequence than the belgian one. * Import the XML > Observation: The newly created tax is used even if the partner is from Belgium. Why the fix: ------------ If the partner has a country set we only select tax from the same country. If not we fallback to the previous behavior of selecting the first tax matching opw-5928724
This change corrects how rounding amounts are included in Belgian Peppol invoice XML files. It helps prevent valid invoices with down payments from being rejected by Peppol validation due to mismatched payment totals.
Original PR description
With l10n_be: - Create the following sales order: Lines 1: qty: 25, Price: 23.90, Tax: 6% Line 2: qty: 25, Price: 17.00, Tax: 21% - Create a dowpayment for this SO at 50% - Generate the peppol xml,…
With l10n_be: - Create the following sales order: Lines 1: qty: 25, Price: 23.90, Tax: 6% Line 2: qty: 25, Price: 17.00, Tax: 21% - Create a dowpayment for this SO at 50% - Generate the peppol xml, you get the following error (link to the validator: https://peppol-ap.test.odoo.com/filevalidator/validate): Peppol Error [code=106]: Schematron Validation Error The XML document did not pass the Schematron validation. Schematron Validation failed with error: Fatal: [BR-CO-16]-Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114). In the override of _ubl_add_legal_monetary_total_payable_rounding_amount_node, the payable_rounding_amount was not added to the PayableAmount node like in the original method. opw-6067736 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
Purchase order PDFs now correctly calculate section subtotals when sections contain subsections. This prevents misleading zero totals and helps buyers and vendors review order amounts accurately.
Original PR description
Steps to reproduce: 1- Install Purchase app 2- Create a new purchase order 3- Add a section with two subsections, and add a product in each subsection 4- Confirm the PO and print Issue: The section subtotal is equal to 0 Expected behavior: Section subtotal should be equal to the sum of all subsections Why this happens: After introducing sections and subsections in this commit bc6592a, the subtotal calculation in Purchase does not follow the same logic as in Sales and Invoicing which work properly. The code relied on `current_subtotal` for calculation, which would reset after each subsection and section. By the time we display the section subtotal, the attribute value would be 0. Fix: Implemented the same logic used in the other apps. opw-6086465
This fix makes quote blocks in the HTML editor behave more predictably when users delete content or create lists. Images, tables, and lists can now stay properly inside quoted sections, reducing formatting surprises while editing web content.
Original PR description
Description of the issue this PR addresses: - Pressing Backspace inside a blockquote that has visible content but no text content removes the blockquote instead of the content. The content (image or table) gets moved outside of the blockquote. - Lists could not be created inside a `blockquote`. Desired behavior after PR is merged: - Backspace removes the inner content first when blockquote contains nodes. - Lists can be created directly inside a blockquote. task-5864080 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258900 Forward-Port-Of: odoo/odoo#245011
Leave balance reports now use an employee’s current department when filtering and grouping results. This prevents duplicate employee entries after department changes and gives managers a clearer, more accurate view of time off balances.
Original PR description
Steps to reproduce: ------------------------- 1. Install the Time Off module. 2. Go to Time Off > Management > Allocations, create an allocation for an employee, and approve it. 3. Go to Reporting >…
Steps to reproduce: ------------------------- 1. Install the Time Off module. 2. Go to Time Off > Management > Allocations, create an allocation for an employee, and approve it. 3. Go to Reporting > Balance and apply the filter Department > Employee. 4. Change the employee’s department. 5. Create an allocation for the same employee and approve. 6. Apply the Department > Employee filter again. Observed behaviour: ---------------------------- After a department change: * Existing allocations keep the old department * New allocations use the new department As a result, duplicate employee entries appear in the report Cause: ---------- It is using allocation.department_id. Allocations store the department at creation time, which may differ from the employee’s current department, causing an incorrect report filtering. Solution: ------------ Fetch department_id from hr_version instead of hr_leave_allocation in the hr_leave_employee_type_report. This ensures: * Leave balances always follow the employee’s current department * Correct aggregation when grouping by Department → Employee opw-5220577 Before: <img width="1238" height="857" alt="image" src="https://github.com/user-attachments/assets/15e1293b-dc50-4067-a12f-079c046c2074" /> After: <img width="1247" height="824" alt="image" src="https://github.com/user-attachments/assets/feea32de-0d9c-4eef-9ae5-639f4658560c" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258562
Partner autocomplete now skips VAT numbers returned in an invalid format instead of applying them and triggering a validation error. This prevents partner creation or invoice workflows from being blocked when full autocomplete data cannot be retrieved due to missing IAP credits.
Original PR description
### Issue: When autocompleting some partners, the returned VAT could be in an invalid format, leading to a validation error You need `base_vat` installed to get the issue ### Cause: The partner autocomplete feature relies on IAP credits for full data retrieval When no credits are available, only the VAT is returned if it was already fetched before In some cases, this VAT value is incorrectly formatted, which triggers a validation error when applied to the partner ### Fix: Invalid VAT values returned by the autocomplete are now ignored to prevent errors Since the correct VAT cannot be retrieved without IAP credits, the value is simply removed ### Steps to reproduce: - Install `l10n_cy` (we need a localization to enable base_vat) - Create a new partner from an invoice - Enter TONYO 360 and select the autocomplete suggestion Before the fix: The VAT field is filled with an invalid value, causing a validation error opw-6030164 Forward-Port-Of: odoo/odoo#255476
The accounting invoice widget now only shows outstanding payments or credits from the same company as the invoice. This prevents users in multi-company setups from selecting payments that cannot be applied, reducing confusion and validation errors.
Original PR description
The invoice outstanding credits/debits widget currently displays all reconcilable items for a partner across the same account, regardless of the company they belong to. In multi-company environments,…
The invoice outstanding credits/debits widget currently displays all reconcilable items for a partner across the same account, regardless of the company they belong to. In multi-company environments, specifically when accounts have been merged, this allows users to see and try to reconcile payments from Company A into an invoice from Company B. This action eventually triggers a validation error stating that entries must belong to the same company. This commit adds a company filter to the widget's logic to ensure only relevant outstanding payments are suggested, preventing cross-company reconciliation errors and improving UX. **Description of the issue/feature this PR addresses:** This PR fixes a validation error in multi-company environments where the invoice_outstanding_credits_debits_widget suggests payments or credit notes belonging to a different company than the current invoice. The issue typically arises when a partner has outstanding transactions in multiple companies and the accounts (e.g., Account Receivable) have been merged, allowing the widget to query lines that are not valid for the current record's company context. **Current behavior before PR:** When viewing an invoice for Company A, the "Outstanding Credits/Debits" widget displays all reconcilable account.move.line records for that partner that match the account type, regardless of their company_id. If a user clicks "Add" on a payment that belongs to Company B, Odoo attempts to reconcile them, resulting in a traceback or a validation error: "Invalid Operation: All tracebacks/entries must belong to the same company." This creates confusion for the end-user, as they are presented with "ghost" credits that cannot actually be applied. **Desired behavior after PR is merged:** The invoice_outstanding_credits_debits_widget (and the underlying logic in account.move) will strictly filter the suggested outstanding items by self.company_id. Users will only see and be able to reconcile payments, credit notes, or debits that belong to the same company as the invoice they are currently processing. This ensures data integrity and a seamless UX in multi-company setups. **Steps to reproduce:** 1) Enable Multi-Company: Ensure you have at least two companies (e.g., Company A and Company B) active in your database. 2) Chart of Accounts Setup: In both companies, use the same account for Receivables (or merge them so they share the same ID/Code if testing a migrated environment). 3) Ensure the account is marked as Allow Reconciliation. 4) Create a Payment in Company B: 5) Post the payment so it remains as an "Outstanding Receipt". 6) Create an Invoice in Company A 7) Confirm/Post the invoice. 8) Check the Widget: Scroll down to the bottom of the Invoice form in Company A. 9) Observe the "Outstanding Credits" widget. The Error: The payment from Company B will appear as an available credit for the invoice in Company A. 10) Click on "Add". A validation error (UserError) will pop up: "All entries must belong to the same company." **video** https://drive.google.com/file/d/1PfBxupP8t-t21wsP2FIgNXFnTP0Zq140/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#255875
Restaurant staff will now see table occupancy consistently across all POS devices, even when a waiter opens a table but has not added items yet. This prevents another employee from mistakenly thinking the table is still free and improves coordination during service.
Original PR description
When a waiter selects a table without adding any items and returns to the floor screen, the table appears as occupied (green) on their device but not on other devices in the same POS session. Steps to reproduce: ------------------- * Open POS session on device A * Open same POS session on device B * On device A: click a table, don't add items, go back to floor * On device B: observe the table does not appear as occupied > Observation: Empty table assignments were not being synced to the server, so other devices couldn't detect the table occupancy. Why the fix: ------------ Also treat orders with a table_id as pending so they sync immediately when a table is opened. The backend already supports this: pos.order can be created with just table_id, and pos_restaurant._get_open_order looks orders up by table_id for table-based sync. opw-5236119
Fixes inventory valuation when stock is stored in internal locations that are not tied to a specific warehouse, such as subcontracting or rental locations. This prevents inflated unit costs and stock values, giving businesses more accurate inventory reports and financial valuation.
Original PR description
This commit addresses two valuation issues with respect to transit/internal locations without specific warehouses (such as the subcontracting location): 1. The `avg_cost` (unit cost) of products can…
This commit addresses two valuation issues with respect to transit/internal locations without specific warehouses (such as the subcontracting location): 1. The `avg_cost` (unit cost) of products can drastically differ from its expected value since the valued quantity considered in the product total value is not necessarily the `qty_available` but the avg cost is computed as such: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L272-L273 2. The `value` of stock.quants is unexpectedly impacted by the quantity present these other locations for the same reasons: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/stock_quant.py#L57-L65 ### Steps to reproduce: - In the settings enable Multi-Steps Routes - Create a storable with an avco perpetual valuation with a cost of 5$ - Click the `On hand` smart button > Update Quantity - Put 1 unit in WH/Stock and 2 units in Subcontracting - Go to Inventory > Reporting > Stock #### > The unit cost of your product is 15$ instead of 5$ - Click on locations on the line and remove the `internal` filter #### > The value in WH/Stock is 15$ instead of 5$ and the one in Subcontracting is 30$ instead of 10$ ### Cause of the issue: The total value of a product is computed with an additional valuation context in order to consider valuated locations and dates properly: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L202-L205 https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L231-L247 https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L264-L266 However, the `avg_cost` is computed by dividing this total value by the `qty_available` with apriori completely different context: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L271-L273 In teh present use case, the `qty_available` outside of the valuation context is 1, while the valuated quantity was 3 (as it did consider all of the internal valuated locations (e.g. Subcontracting)) because of these lines: https://github.com/odoo/odoo/blob/93095e1e9507fde18aefe91aac8c9cb53cadc2f3/addons/stock_account/models/product.py#L202-L205 https://github.com/odoo/odoo/blob/93095e1e9507fde18aefe91aac8c9cb53cadc2f3/addons/stock_account/models/product.py#L361-L363 ### Additional issue: The variable definition in this loop is incorrect: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L251-L262 Since `prodcuts` is defined just above: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L202-L205 and is expected to be used as such unaltered: https://github.com/odoo/odoo/blob/1cf08a339c4b46d23c58beecb563b3438e64f0e3/addons/stock_account/models/product.py#L264-L266 In particular, the current variable declaration lead only to a valid process of the last `cost_method` group. As this variable is only introduced for the purpose of the loop computation we rename it. opw-5959720 opw-5883980 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures Spanish SII tax reports include REAGYP compensation amounts when calculating the deductible quota sent to AEAT. Businesses using this agricultural tax regime will have more accurate electronic tax submissions and avoid underreporting deductible amounts.
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#258932 Forward-Port-Of: odoo/odoo#256586
Mobile users can now edit website profile pages without hitting an error. The fix uses the same profile editing dialog already used on desktop, improving consistency and avoiding a broken mobile experience.
Original PR description
# How to reproduce - Install the eLearning module - On the website, go to the Courses tab - View a user (Administrator for example) - In mobile view, click on Edit # The problem An traceback is shown and the user cannot edit their profile # Why This commit (https://github.com/odoo/odoo/commit/69785c1a64d61f2831804bcdcc4887ad43d27fbb) improved the profile edition. It is mentioned that they moved away from the simple bootstrap modal and used an OWL view instead. However, for the mobile view, they left a call to a modal that does not exist. This fix removes the call to the undefined modal and replaces it with the same OWL Dialog used in the desktop view (thanks to the .o_wprofile_editor class) opw-5960586 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251503
This fixes an issue on mobile where the chat message box could become unusable if the navigation menu was still open. Users can now tap the composer and bring up the keyboard reliably, improving mobile chat usability without changing the chat workflow.
Original PR description
**Description of the issue this PR addresses:** On mobile devices, the chat composer becomes unresponsive when the navigation menu `navbar-toggler` is open.…
**Description of the issue this PR addresses:** On mobile devices, the chat composer becomes unresponsive when the navigation menu `navbar-toggler` is open. https://github.com/user-attachments/assets/8ef01ec6-4a44-41d3-8b86-74f68caf47ef Steps to reproduce: 1. Open the website in a mobile view. 2. Tap the navbar toggler to open the mobile menu. 3. Without closing the menu, open the chat window. 4. Tap on the message composer text area. → The composer is not accessible. This happens because the bootstrap `Offcanvas` (used by the `navbar-toggler`) traps focus by listening for `focusin` events bubbling up to the document. When the composer is tapped, the Offcanvas intercepts the event and immediately steals focus back to itself, dismissing the virtual keyboard. This commit stops the event propagation at the composer level, ensuring the composer can reliably retain focus in responsive views without interference from active menus. Task-[5954657](https://www.odoo.com/odoo/project/1519/tasks/5954657) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258974 Forward-Port-Of: odoo/odoo#250294
Odoo now better handles cases where the same incoming email is processed at the same time for multiple mail aliases. This prevents duplicate business records from being created, improving data consistency for teams using email-driven workflows such as helpdesk.
Original PR description
Concurrent processing of emails with the same `Message-Id` can create duplicate records. ### Steps to reproduce 1. Configure multiple mail aliases (e.g., two helpdesk teams). 2. Send one email with…
Concurrent processing of emails with the same `Message-Id` can create duplicate records. ### Steps to reproduce 1. Configure multiple mail aliases (e.g., two helpdesk teams). 2. Send one email with both aliases as recipient. The Mail Transfer Agent may invoke `odoo-mailgate.py` once per recipient, resulting in concurrent processing of the same email in separate transactions. We expect one record per alias/team, but duplicates may be created. ### Cause This is a race condition in the `Message-Id` deduplication logic, caused by concurrent transactions and PostgreSQL snapshot isolation. Odoo uses the `REPEATABLE READ` isolation level. This means that each transaction takes a snapshot of the database at its first query and cannot see changes committed by other concurrent transactions. When two concurrent transactions process the same email: 1. Both enter `message_process` and take their snapshot. 2. Both search for the `Message-Id`. Because their snapshots don't include each other's work, both find nothing. 3. Both create records. Even if one transaction commits before the other performs the check, the second transaction still uses its original stale snapshot and create duplicates. ### Fix After the initial duplicate check, attempt to acquire a transactional advisory lock on a hash of the `Message-Id` using `pg_try_advisory_xact_lock`. If another transaction is already processing the same email and holds the lock, the call returns false and the email is treated as a duplicate. If the lock is acquired, processing continues as normal. opw-5116492 Forward-Port-Of: odoo/odoo#258847 Forward-Port-Of: odoo/odoo#250027
Fixes an issue where newly added stock operation lines could disappear from the detailed moves view after refreshing or using actions like Put in Pack. This keeps warehouse users' newly entered lines visible and reduces confusion during receipt or picking processing.
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#247170Customers buying event tickets through Point of Sale with an online payment method will now see the ticket download button as expected. This fixes a checkout screen issue that prevented immediate access to purchased event tickets after online payment flows.
Original PR description
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and…
**Steps to reproduce:** - Set up an event, go put it's state to Annonced - Set up any online payment method (Demo also triggers the bug) - Go to a PoS that sells the event tickets - Purchase one and pay with the online payment method - Once on the ticket screen, the button to download the event tickets is not displayed **Why the fix:** The normal flow only works for offline payment methods, because we check if the ordered is either paid or invoiced before setting all the values needed by the frontend regarding the ticket registration. The problem is that with an online payment method, once we enter the **read_pos_data** method that sets the values for the frontend, the order is still in draft, so we just return without doing anything. We now set the values regardless of the order's status and send the confirmation mail in the same way as if it was an online payment. In the case of an online payment, the mail will be sent by the **action_pos_order_paid** function that is called once the payment is processed. A test might be a bit weird to make as we don't have a bridge for pos_online_payment and pos_event, and that we would need to mock the server's answer to be able to pay for the online payment and check that we have the needed values. So the setup for pos_event would have to be copied into pos_online_payment to test it and it would only be ran if both modules are installed. opw-5438432 Forward-Port-Of: odoo/odoo#257593 Forward-Port-Of: odoo/odoo#249306
This fix prevents manually entered dates from reverting to an older value after saving a form. It improves reliability for users who type dates directly into date fields, reducing the risk of incorrect information being saved.
Original PR description
Step to reproduce: - Go on view form with a date field - Set the date with the input by typing the date with day and month (mm/dd or dd/mm), then press enter - Save the record - Redo the second step by with a different date - Save the record The assignation of the state.value done when closing the datepicker is useless and can put old a value in the state. The datepicker hasn't finished to update of the record that the assignation put back the old value of the record back in the state. The reason why it happens only after a save is still unknown. task-6095467 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a problem where navigating back in the documents module (specifically in kanban and list views) caused the page to reload unnecessarily. The fix ensures correct page restoration and avoids reopening the same folder after a back navigation, improving the user experience. This prevents data inconsistencies and frustration for users.
This update fixes a calculation error in the employment bonus payments for Belgian companies using the l10n_be_hr_payroll module. The change ensures that bonus calculations now precisely align with the requirements outlined by Belgian social security regulations, as detailed in the official documentation. This correction guarantees accurate and compliant bonus payments.
Original PR description
The employment bonus computation was missing two roundings steps that are explicitely asked for in the following documentation: https://www.socialsecurity.be/employer/instructions/dmfa/fr/latest/instructions/deductions/workers_reductions/workbonus.html
This update fixes an issue where refunds weren't correctly reflected when calculating outstanding balances in the POS system. Previously, only regular orders were considered, leading to inaccurate due amounts. Now, refund orders with negative totals are included, ensuring accurate due calculations and a better user experience.
Original PR description
Step to reproduce - install "pos_settle_due" - have a customer, A and a pos with payment method "customer Account" - start pos, add 3 qty of product with unit price 10$ with partner A - use payment method "customer Account" i.e. of type "pay_later" (do not invoice orders) - refund 1 qty of previous order using same payment method - go to partner list, notice A has 20$ as due - click on "hamburger btn" > settle due amount Observation: - notice we only get the order amount as due i.e order with 30$ - we should have received the refund order too, so that net due of 20$ can be processed Cause: - currently, we didn't considered refunds orders at all, when settling dues Fix: - now we consider order with total < 0 i.e refund orders to be included for settlement opw-5869313 Forward-Port-Of: odoo/enterprise#113458 Forward-Port-Of: odoo/enterprise#107883
This update corrects a bug in how Odoo calculates depreciation for assets with shortened fiscal years. Previously, the system incorrectly skipped months during depreciation, particularly in the transition between fiscal years. This fix ensures accurate depreciation calculations for companies using non-standard fiscal year cycles.
Original PR description
When a company has a shortened fiscal year defined via account.fiscal.year (e.g. May-December), the depreciation board computation for degressive assets incorrectly computes the start of the next…
When a company has a shortened fiscal year defined via account.fiscal.year (e.g. May-December), the depreciation board computation for degressive assets incorrectly computes the start of the next fiscal year using `date_from + 1 year` instead of querying the actual next fiscal year. This causes entries for the months between the wrong and correct FY start (e.g. January-April) to be skipped entirely. Step to reproduce: - Create a company with a fiscal year starting in May (e.g. May 1st 2025 to 31st December 2025) - Create an asset with a start date in the 1 December 2025, with a 24 months duration and degressive method - Compute the board and observe that entries from January to April 2026 are missing Fix the FY boundary detection in _recompute_board to query the fiscal year containing the day after the current period end, revert the effective_start_date logic in _compute_board_amount that was masking the root cause, and move the prorata date clamping to _create_move_before_date where it is needed for disposal. opw-6016834 Forward-Port-Of: odoo/enterprise#113521
This update fixes an error in how invoice periods are calculated for subscriptions with 'Align to Period Start' enabled. Previously, invoices displayed an incorrect date range. Now, invoice periods accurately reflect the subscription's start date and end on the last day of the month, ensuring accurate billing.
Original PR description
Steps to reproduce: ------------------------------------- 1. Install the Subscription module. 2. Go to Subscription > Configuration > Recurring Plans. * Open a Monthly recurring plan and enable Align…
Steps to reproduce: ------------------------------------- 1. Install the Subscription module. 2. Go to Subscription > Configuration > Recurring Plans. * Open a Monthly recurring plan and enable Align to Period Start. 3. Create a new Subscription: * Select the configured monthly plan. * Add any subscription product. * In the Other Info tab, set a Start Date in the past on the 1st day of a month (e.g., 01/11/2025). 4. Confirm the subscription. 5. Create a draft invoice. Observation: ----------------------------------- In the invoice line, you see the message: `61 days 11/01/2025 to 12/31/2025` It should be: `1 Month 11/01/2025 to 11/30/2025` Issue: ----------------------------------- https://github.com/odoo/enterprise/blob/a5a76de5f25483afa5432ed333c48d78832f128c/sale_subscription/models/sale_order_line.py#L376-L378 In `_get_invoice_line_parameters`, the computation attempts to find the next 1st day of the month However, `new_period_stop` already includes the billing period. When `new_period_stop` is in the past, an extra month is added through `new_period_stop + relativedelta(months=1)`, resulting in an incorrect period range Solution: ----------------------------------- Use `new_period_start` as the anchor point for period computation. Ensure the billing period ends on the last day of the starting month when Align to Period Start is enabled For upsell orders, the fix is NOT applied because for upsells, `new_period_stop` is already set to the parent subscription's `next_invoice_date`, which represents the correct billing boundary. opw-5920036
This update resolves an issue where the AI composer was causing instability in the base mail composer. The fix ensures that focus events are correctly passed, preventing a crash when the AI composer triggers focus. This improves the overall reliability of the AI composer within the Enterprise module.
Original PR description
**Purpose of this PR:** The AI composer patch overrides `Composer.onFocusin()` but did not forward the focus event to the base handler. This used to be harmless while the base mail composer focus handler did not use the event. Since odoo/odoo#258974, the mail composer now uses the event to stop `focusin` propagation, so dropping it makes the base handler crash when AI composer focus is triggered. This commit fixes the AI composer patch by forwarding the focus event to the base handler, preserving the expected handler contract. Related: odoo/odoo#258974 Task-5954657 Forward-Port-Of: odoo/enterprise#113763
This update resolves a crash issue that occurred when confirming rental orders with kit products using multiple pick locations. The change utilizes a safer method to handle multiple pick transfers, preventing a 'singleton error' and ensuring rental orders can be processed correctly. This improves the reliability of the rental product functionality.
Original PR description
Problem: When you confirm a rental order that has a kit product whose components use two different pack locations Odoo crashes with a singleton error. You get this singleton error because Odoo tries…
Problem: When you confirm a rental order that has a kit product whose components use two different pack locations Odoo crashes with a singleton error. You get this singleton error because Odoo tries to assign both picks as the `return_id` because they share the same `sale.order.line` here: https://github.com/odoo/enterprise/blob/2212b3f3f3d90894dd6351defe0d3ca090584955/sale_stock_renting/models/sale_order_line.py#L404
Purpose: Use [:1] to safely handle the case where multiple pick transfers are created, avoiding a crash when assigning return_id which expects a single record.
Steps to Reproduce on Runbot:
1. Enable mutli-step routes and rental transfers.
2. Set the warehouse to 3-step delivery.
3. Copy the existing packing location.
4. Copy the existing pick operation type and set the destination location to the new packing location.
5. Create a new route.
6. Create new rules on this new route with the following configurations:
1. Rule 1
1. Action: Pull
2. Source location: WH/Stock
3. Destination location: Partners/Customers
4. Operation type: The new pick operation type
2. Rule 2
1. Action: Push
2. Source location: New pack location
3. Destination location: WH/Output
4. Operation type: Pack
3. Rule 3
1. Action: Push
2. Source location: WH/Output
3. Destination location: Partners/Customers
4. Operation type: Delivery
7. Create 2 component products tracked by inventory, and apply the new route on one of the component products.
8. Create a new rental product with a kit, which has the 2 component products.
9. Create a new rental order for the kit product and confirm it.
opw-6026918
Forward-Port-Of: odoo/enterprise#112543