Friday, June 26, 2026
168 changes
8 changes
Enhancements to existing features
The bank reconciliation screen now has a simpler, dedicated layout on mobile devices, making it easier to review and match items. It also shows the statement date, reference, and remaining balance above the list so users have the needed context while reconciling.
Original PR description
Current behavior before PR: On mobile devices, the bank reconciliation dialog relied on the base kanban view of account move line, which is difficult to handle and lacked contextual information about…
Current behavior before PR: On mobile devices, the bank reconciliation dialog relied on the base kanban view of account move line, which is difficult to handle and lacked contextual information about the statement being reconciled. Desired behavior after PR is merged: The bank reconciliation flow on mobile uses a dedicated kanban view with a simplified layout. An informational line is displayed above the main view, showing the statement date, reference, and remaining balance for better context. Changes implemented: - Added a mobile-specific kanban view for bank reconciliation dialog. - Displayed an information line above the kanban view with statement date, reference, and balance like desktop view for bank reconciliation dialog. - Moved 'onSelectionChanged' to 'BankRecSelectCreateDialog' and shared it through 'bankRecInfo', moved 'remainingAmountFormatted' into the state, and removed the duplicated getters from the list and kanban renderers. - Kept the existing desktop layout and behavior unchanged. - Added a HOOT test to check the mobile bank reconciliation dialog. task-5502469 Forward-Port-Of: odoo/enterprise#106565
Resolved issues and error corrections
This update prevents the salary configurator from crashing when the company car option is enabled without a car model already selected. It improves reliability for Belgian contract salary setups, especially in databases created without demo data.
Original PR description
## Steps to Reproduce: 1. Install `l10n_be_hr_contract_salary` without demo data. 2. Create a Belgian company and switch to it. 3. Create an employee. 4. Create a contract for the employee. 5. Click Generate Offer and open the Salary Configurator. 6. Enable the 'Company Car (To order)' option. ## Error: `AttributeError: 'NoneType' object has no attribute 'split'` ## Cause: When the salary configurator is used without demo data, no car model is selected. The method assumes that select_wishlist_car_total_depreciated_cost always contains a value and directly calls split() on it, resulting in an error, when the field is None. ## Fix: This commit checks that both the company car option is enabled and a car model has been selected before trying to extract the model ID. sentry-7554712017 Forward-Port-Of: odoo/enterprise#121650 Forward-Port-Of: odoo/enterprise#121138
7 changes
Enhancements to existing features
The bank reconciliation screen now has a simpler, mobile-friendly layout that is easier to use on small screens. It also shows key statement details and the remaining balance above the list, giving users better context while they reconcile payments.
Original PR description
1 change
Resolved issues and error corrections
This update prevents an error when enabling the company car option in the Belgian salary configurator without demo data. It ensures the system only looks up a car model when one has actually been selected, so the offer process continues smoothly.
Original PR description
## Steps to Reproduce: 1. Install `l10n_be_hr_contract_salary` without demo data. 2. Create a Belgian company and switch to it. 3. Create an employee. 4. Create a contract for the employee. 5. Click Generate Offer and open the Salary Configurator. 6. Enable the 'Company Car (To order)' option. ## Error: `AttributeError: 'NoneType' object has no attribute 'split'` ## Cause: When the salary configurator is used without demo data, no car model is selected. The method assumes that select_wishlist_car_total_depreciated_cost always contains a value and directly calls split() on it, resulting in an error, when the field is None. ## Fix: This commit checks that both the company car option is enabled and a car model has been selected before trying to extract the model ID. sentry-7554712017 Forward-Port-Of: odoo/enterprise#121650 Forward-Port-Of: odoo/enterprise#121138
1 change
Resolved issues and error corrections
Refreshing a tax report from the returns screen no longer sends users back to the kanban view or shows an error. The report now keeps track of the correct report context after refresh, so users can continue working without interruption.
Original PR description
3 changes
Enhancements to existing features
Helpdesk now prevents duplicate tag names in the English locale, treating names like "Bug" and "bug" as the same. This helps keep tags consistent, avoids confusion for users, and automatically cleans up existing duplicates by keeping only one version.
Original PR description
Added a unique index to ensure that tag names in the English locale (en_US) are case-insensitively unique.
This change prevents duplicate tag names such as:
---------------------------------------------------------------------
- Bug, bug
- Saas, saas, SaaS
When duplicates exist, only the one with the lowest ID is retained, and others are removed.
A user-friendly error is raised if a new tag with a conflicting name is created.
task: 46790102 changes
Resolved issues and error corrections
This fix ensures invoice lines are properly included in tax reports when grouped taxes are used. It now recognizes the relevant child tax tags, so report totals are more accurate and no longer miss lines tied to those taxes.
Original PR description
When using group taxes, the base invoice lines only store the parent tax in the `account_move_line_account_tax_rel` table. Because of this, if a child tax within the group contains a specific tax report tag, the generic report query would previously fail to pick up those base lines. This commit updates the SQL join conditions in `l10n_ph_generic_report.py` to also match `account_tax.id` against the child taxes of the linked parent tax using the `account_tax_filiation_rel` table. This ensures that base lines are correctly reported under the tags of their respective child taxes. Task-6278098
3 changes
Enhancements to existing features
This update prepares the Austrian localization for a VAT change effective July 1, 2026, reducing the rate from 10% to 4.9% for certain food categories. It also adjusts the related chart of accounts and tax return mapping so accounting and reporting stay correct.
Original PR description
From first of July 2026, the VAT will change from 10% to 4.9% for some food categories. Adapt the taxes, the CoA and the tax return accordingly. task-6273259 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268278
This change prevents the system from creating duplicate draft entries when the scheduled import runs for Belgian SODA files. It restores the previous behavior to avoid repeated imports and reduce confusion in accounting records.
Original PR description
Since this commit: https://github.com/odoo/enterprise/commit/a0c9e9b5c0ed8135d77c343c819c1fa918356794 users are experiencing some duplicate draft move when the cron is running. It's because we don't skip the files when it already exist, we now add a number of imported count. This commit will revert this change to avoid the problem, and we will contact codabox to find a better way to deal with files imported the same month. task-6299508 Forward-Port-Of: odoo/enterprise#121472
This fix prevents module upgrades from failing for older databases that use the Italian tax reporting package. It removes outdated report entries before the upgrade so the new report formulas can be installed cleanly.
Original PR description
Steps to reproduce: - Create a database with `l10n_it_reports` on a version before PR #264294 - Switch to current `17.0` - Upgrade module `l10n_it` - An error is raised Upgrading a database with `l10n_it_reports` installed raises an error if the database was created before that PR In that PR, we modified the formulas of several report expressions to use subformulas instead of simple aggregations. During upgrade, the ORM attempts to insert the updated expressions while the old ones still exist, violating the UNIQUE constraint on `(report_line_id, label)` in `account.report.expression` Only happens on upgrade, not on a fresh install. A migration script is added to delete the outdated expressions before the upgrade runs Ticket [link](https://www.odoo.com/odoo/project.task/6299385) opw-6299385 Forward-Port-Of: odoo/odoo#271320
This change stops the Point of Sale ticket screen from refunding lines that are already refunds or have been fully refunded. It helps avoid accidental duplicate refunds and keeps refund records accurate.
Original PR description
In the ticket screen, clicking an order line selected it for refund and incremented its quantity without checking whether the line could actually be refunded. As a result, a refund order (whose lines carry a negative quantity) could itself be refunded, and already fully refunded lines could be refunded again. opw-6314527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271109
The Spanish Mod 349 report now keeps invoices that were paid during the selected period. This fixes an issue where paid invoices could be incorrectly left out of the report, helping ensure the filing is complete and accurate.
Original PR description
The mod349 report engine has been refactored to use tax tags (commit : 5f36778288a1b60245acec74677421666448351f). To avoid redundancies, the query used to get the invoice lines to include is designed to remove the amounts that have been reconciled with a credit note during the selected period. However, the current query removes the lines from any invoice that is reconciled with a move created in the period. As a result, invoices that have been paid in the period are also removed from the report. opw-6250491 Forward-Port-Of: odoo/enterprise#119551
When two restaurant orders are merged into one table, previously sent kitchen quantities are now preserved correctly. This prevents already-prepared items from being shown as new and sent to the kitchen again, avoiding duplicate work and confusion.
Original PR description
When transferring an order to a table that already has an open order, identical products are merged into a single line. If both orders were already sent to the kitchen printer, the merged line was…
When transferring an order to a table that already has an open order, identical products are merged into a single line. If both orders were already sent to the kitchen printer, the merged line was incorrectly marked as new and had to be sent again. Steps to reproduce: ------------------- * Open table 1, add product A (2 units) and product B, send to kitchen * Open table 2, add product A (3 units) and product C, send to kitchen * On table 2, transfer/merge the order to table 1 > Observation: product A shows 2 units as new and must be sent to the kitchen printer again, although all quantities were already sent. Why the fix: ------------ When merging preparation history for identical lines, handlePreparationHistory overwrote the destination sent quantity with the source one instead of summing both. The kitchen diff then treated the missing quantity as new changes. A unit test will be added in 18.3. opw-6246470 Forward-Port-Of: odoo/odoo#271828 Forward-Port-Of: odoo/odoo#267915
Automatic reconciliation now preserves the original payment reference on matched bank statement lines instead of replacing it with the account name. This keeps labels consistent across reconciliation methods and makes it easier for users to identify transactions correctly.
Original PR description
### Issue: When creating an automatic reconciliation rule by assigning the same account to multiple bank statement lines, the rule incorrectly overrides the original payment reference of subsequent…
### Issue: When creating an automatic reconciliation rule by assigning the same account to multiple bank statement lines, the rule incorrectly overrides the original payment reference of subsequent lines with the account name This creates an inconsistent user experience Using the "Set Account" button directly keeps the statement line payment reference as the journal item label However, clicking the automatically generated reconciliation model button replaces that reference with the account name Before the fix, clicking the automated rule button on a third matching line overrides its label with the account name instead of keeping its unique reference ### Cause: In `_create_reconciliation_rule`, when an automatic model is generated, the dictionary used to create the counterpart line explicitly set `label` to `rule_data['account'].name` When a reconciliation model line has a specific label defined, Odoo uses it to replace the statement line `payment_ref` on the generated counterpart move lines Removing this default value allows the system to fall back on the original payment reference ### Steps to reproduce: - Install `account_accountant` - Go to the Bank Reconciliation widget from the Accounting Dashboard - Create 2 statement lines without partners (e.g., Ref: "Test Ref 1" and "Test Ref 2") - Set the same account on both lines using Set Account - This automatically creates a Reconciliation Rule named after the account - Create a 3rd statement line with a matching reference (e.g., "Test Ref 3") - Click the newly available automatic reconciliation button for this line Before the fix, checking the generated entry label shows the account name instead of "Test Ref 3" To check unfold the details, click on the pencil icon of a line opw-6246833 Forward-Port-Of: odoo/enterprise#119133
Current behavior before PR: On mobile devices, the bank reconciliation dialog relied on the base kanban view of account move line, which is difficult to handle and lacked contextual information about…
Current behavior before PR: On mobile devices, the bank reconciliation dialog relied on the base kanban view of account move line, which is difficult to handle and lacked contextual information about the statement being reconciled. Desired behavior after PR is merged: The bank reconciliation flow on mobile uses a dedicated kanban view with a simplified layout. An informational line is displayed above the main view, showing the statement date, reference, and remaining balance for better context. Changes implemented: - Added a mobile-specific kanban view for bank reconciliation dialog. - Displayed an information line above the kanban view with statement date, reference, and balance like desktop view for bank reconciliation dialog. - Moved 'onSelectionChanged' to 'BankRecSelectCreateDialog' and shared it through 'bankRecInfo', moved 'remainingAmountFormatted' into the state, and removed the duplicated getters from the list and kanban renderers. - Kept the existing desktop layout and behavior unchanged. - Added a HOOT test to check the mobile bank reconciliation dialog. task-5502469 Forward-Port-Of: odoo/enterprise#106565
Resolved issues and error corrections
The stock forecast report now converts all quantities to the product’s main unit of measure before displaying them. This prevents mixed units from appearing on the same graph and makes the forecast easier to read and interpret.
Original PR description
When a stock move's UoM differs from the product template's UoM, the report aggregation incorrectly shows data for both UoMs of stock move.quantity on the same graph. All moves should be normalized…
When a stock move's UoM differs from the product template's UoM, the report aggregation incorrectly shows data for both UoMs of stock move.quantity on the same graph. All moves should be normalized to the UoM of the product for which we are viewing the forecast. We can do this with: `m.quantity * move_uom.factor / pt_uom.factor AS quantity` If the UoMs of the stock move and the product template are identical, as is the case most of the time, this simply multiplies by one, and the query behaves exactly as it did before. But if the units are distinct, the move UoM is converted into the product template UoM so that the data for stock move quantity is normalized to one shared unit across the entire forecast graph. **E.g.**: m.quantity == 500g m.UoM == g m.UoM.factor == 1 pt.UoM == kg pt.UoM.factor == 1000 500g * 1 / 1000 ==> .5kg **Steps to Reproduce on Runbot**: 1. Create a product which uses kg and g. 2. Confirm and Validate a receipt for this product (10 kg for example). 3. Confirm a second receipt for this product in the same UoM kg. 4. Confirm and Validate a delivery for this product with UoM g (500 g for example). 5. View the forecasted graph for the product, and you will see that the y axis is scaled on grams ~500, and the current / future stock moves in the report are still scaled based on kg. opw-6234066 Forward-Port-Of: odoo/odoo#266811
The salary configurator no longer crashes when a user enables the company car option without a car model being selected. This makes the setup process work correctly for companies installed without demo data.
Original PR description
## Steps to Reproduce: 1. Install `l10n_be_hr_contract_salary` without demo data. 2. Create a Belgian company and switch to it. 3. Create an employee. 4. Create a contract for the employee. 5. Click Generate Offer and open the Salary Configurator. 6. Enable the 'Company Car (To order)' option. ## Error: `AttributeError: 'NoneType' object has no attribute 'split'` ## Cause: When the salary configurator is used without demo data, no car model is selected. The method assumes that select_wishlist_car_total_depreciated_cost always contains a value and directly calls split() on it, resulting in an error, when the field is None. ## Fix: This commit checks that both the company car option is enabled and a car model has been selected before trying to extract the model ID. sentry-7554712017 Forward-Port-Of: odoo/enterprise#121650 Forward-Port-Of: odoo/enterprise#121138
This update fixes how French PDP-related records are recalculated so they no longer depend on unrelated company or partner details. It prevents unnecessary rebuilds and reduces the risk of errors or slowdowns when company or contact information changes.
Original PR description
- This removes dependency on account move fields to company : Build error 939448 - This removes dependency on account move fields to commercial_partner_id fields (avoid recompute all moves on partner info change) Forward-Port-Of: odoo/odoo#271978 Forward-Port-Of: odoo/odoo#269701
This change prevents the system from creating duplicate draft entries when the scheduled import runs. It restores the previous behavior so repeated files are not processed in a way that creates extra transactions, reducing confusion and cleanup for users.
Original PR description
Since this commit: https://github.com/odoo/enterprise/commit/a0c9e9b5c0ed8135d77c343c819c1fa918356794 users are experiencing some duplicate draft move when the cron is running. It's because we don't skip the files when it already exist, we now add a number of imported count. This commit will revert this change to avoid the problem, and we will contact codabox to find a better way to deal with files imported the same month. task-6299508 Forward-Port-Of: odoo/enterprise#121472
Automatic reconciliation rules now preserve the original payment reference on bank statement lines instead of replacing it with the account name. This makes labels consistent across reconciliation methods and helps users identify entries more easily.
Original PR description
### Issue: When creating an automatic reconciliation rule by assigning the same account to multiple bank statement lines, the rule incorrectly overrides the original payment reference of subsequent…
### Issue: When creating an automatic reconciliation rule by assigning the same account to multiple bank statement lines, the rule incorrectly overrides the original payment reference of subsequent lines with the account name This creates an inconsistent user experience Using the "Set Account" button directly keeps the statement line payment reference as the journal item label However, clicking the automatically generated reconciliation model button replaces that reference with the account name Before the fix, clicking the automated rule button on a third matching line overrides its label with the account name instead of keeping its unique reference ### Cause: In `_create_reconciliation_rule`, when an automatic model is generated, the dictionary used to create the counterpart line explicitly set `label` to `rule_data['account'].name` When a reconciliation model line has a specific label defined, Odoo uses it to replace the statement line `payment_ref` on the generated counterpart move lines Removing this default value allows the system to fall back on the original payment reference ### Steps to reproduce: - Install `account_accountant` - Go to the Bank Reconciliation widget from the Accounting Dashboard - Create 2 statement lines without partners (e.g., Ref: "Test Ref 1" and "Test Ref 2") - Set the same account on both lines using Set Account - This automatically creates a Reconciliation Rule named after the account - Create a 3rd statement line with a matching reference (e.g., "Test Ref 3") - Click the newly available automatic reconciliation button for this line Before the fix, checking the generated entry label shows the account name instead of "Test Ref 3" To check unfold the details, click on the pencil icon of a line opw-6246833 Forward-Port-Of: odoo/enterprise#119133
When a vendor bill is auto-filled from a purchase order, some invoice details can change and previously generated early payment discount lines could stay out of sync. This update makes those lines refresh or disappear as needed, so invoice lines and journal items stay aligned and the bill totals remain correct.
Original PR description
When a vendor bill is imported and auto-completed from a purchase order, then invoice lines, taxes, fiscal position, and payment terms can change. Existing EPD dynamic lines that lose their epd_key are skipped by sync and keep stale tax tags and amounts, causing mismatches between Invoice Lines and Journal Items. This commit makes EPD sync include keyless existing EPD lines so they are rewritten or removed during dynamic recomputation after PO auto-complete. Journal items remain consistent with the final invoice lines, taxes, and early discount configuration. Ticket [link](https://www.odoo.com/odoo/project.task/6047505) opw-6047505 Forward-Port-Of: odoo/odoo#271981 Forward-Port-Of: odoo/odoo#265539
Steps to reproduce: 1. Install `account_reports` and set fiscal year beginning date for Tax returns. 2. Open Tax Report from the button on Kanban view of account return. 3. Try to refresh from the…
Steps to reproduce: 1. Install `account_reports` and set fiscal year beginning date for Tax returns. 2. Open Tax Report from the button on Kanban view of account return. 3. Try to refresh from the report page. Without debug mode, it will return to returns kanban view and with debug mode, it will go back and a traceback will appear. Cause: The report from kanban view is opened via a python action method, which returns a `ir.actions.client` of `account_report`. In the controller for report, it tries to fetch the `report_id` from `context` [[1]] set during the python method call. But when we refresh page, this action context is wiped out, so when it tries to get the report options in controller via orm call [[2]], the report_id is lost, and it causes traceback. Solution: This commit tries to get the `report_id` from `action stack` which is prepared based on the url. so it fetches the correct report via ORM call. [1]: https://github.com/odoo/enterprise/blob/saas-18.3/account_reports/static/src/components/account_report/controller.js#L23 [2]: https://github.com/odoo/enterprise/blob/saas-18.3/account_reports/static/src/components/account_report/controller.js#L167 task-6240800
This change adds new payroll configuration options in the settings area, making it easier for HR teams to adjust payroll behavior without needing technical help. It helps streamline setup and gives businesses more control over payroll-related preferences.
Original PR description
Task: 6111217
Resolved issues and error corrections
This change stops the planning process from trying to auto-plan or send schedules when no start or end dates have been set. It helps avoid unexpected errors and makes the planning workflow more reliable for users.
Original PR description
Add a guarding condition to the auto-plan or send behavior to avoid doing those operations when no start/end dates are defined --- Task: 6312650
Fixed an issue where partner mapping could be applied automatically on bank statements even when the reconciliation rule was still set to manual. This makes statement handling more consistent and ensures only the right reconciliation rules are suggested to users.
Original PR description
Users may define a reconciliation model for partner mapping by having a matching label and a counterpart item setting only the partner. If the user then opens the transactions or reconciliation menu and creates a statement, partner mapping will occur automatically, even if the model is still set to 'manual'. Steps to reproduce: - Create a reconciliation model with - Label: Contains 'mylabel' - Counterpart Items: set any partner - Open accounting app - From a Bank journal card click 'Transactions' - Create a statement line containing 'mylabel' Issue: Partner will be automatically set according to the reconciliation model, even if it has not been set to 'Automatic'. opw-5480282
Resolved issues and error corrections
This change fixes a visibility issue in Field Service where customers created under a parent company could not be selected when working from one of its branches. It now correctly recognizes the parent company relationship, so users can choose the expected customer record and continue their work without interruption.
Original PR description
**Steps to Reproduce:** 1. Create a branch under an existing company. 2. Create a contact in company (so the contact is visible only to the company). 3. Switch to the branch of the company. 4. Open Field Service and create a new record. 5. In the *Customer* field, try to select the contact created earlier. **Issue:** The contact created under the company is not selectable in the *Customer* field in Field Service. **Current behaviour:** The same contact is visible in the Contacts app, and also selectable in Sales Order — but not in the Field Service. **Expected behaviour:** The contact created under the company should be selectable as a customer in Field Service when the current user is operating from that branch. **Fix:** Modified the condition of python constrains to check parent company also. **Task-5114444**
This fix makes sure recurring products cannot be added to a sales order without a subscription plan, whether they are added manually or through the product catalog. It prevents inconsistent behavior and avoids orders being saved in an invalid state.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install Subscription Module 2. Create and Confirm SO with no recurring plan and a non-recurring product 3. Add a recurring product >…
Steps to reproduce: --------------------------------------- 1. Install Subscription Module 2. Create and Confirm SO with no recurring plan and a non-recurring product 3. Add a recurring product > Save SO > Observe the User Error 4. Now add the same recurring product through Catalog View Observation: --------------------------------------- No User Error raised stating 'You cannot save a sale order with recurring product and no subscription plan.' Issue: --------------------------------------- When you manually add a line and click 'Save', the constraint (`_constraint_subscription_plan`) is triggered and raised `UserError` https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/sale_subscription/models/sale_order.py#L176-L177 When you add a product via the catalog view, it calls `_update_order_line_info` which directly creates/updates order lines, Which do not trigger the python constraint. https://github.com/odoo/odoo/blob/ef9772bba1515bdaf5410c3af5a3e395f562d513/addons/sale/models/sale_order.py#L1926-L1933 Solution: --------------------------------------- Two private helpers are introduced: * `_is_exempt_from_subscription_plan_check`: single source of truth for all exempt states (draft, cancelled, upsell, and legacy upgrade orders). * `_check_recurring_plan_mismatch`: raises a `UserError` when the order has or will have a recurring product but no subscription plan, reusing the exemption helper so both call sites stay in sync. `_constraint_subscription_plan` is refactored to delegate to these helpers, and `_update_order_line_info` is overridden to call `_check_recurring_plan_mismatch` before the catalog update is applied, ensuring consistent validation across both entry points. opw-6194865 Forward-Port-Of: odoo/enterprise#117879