Daily updates from Odoo
Tuesday, September 2, 2025
79 changes
27 changes
Resolved issues and error corrections
This fixes an issue where refunds for products tracked and valued by lot could leave the related stock transfer unvalidated after closing a Point of Sale session. The correction removes invalid empty stock lines instead of leaving them with zero quantity, helping inventory and accounting records stay accurate automatically.
Original PR description
When refunding a product that was lot valuated, the picking would not be validated automatically. Steps to reproduce: ------------------- * Create a product tracked by lot, and valuated by lot * Open…
When refunding a product that was lot valuated, the picking would not be validated automatically. Steps to reproduce: ------------------- * Create a product tracked by lot, and valuated by lot * Open PoS and create an order with this product * Validate the order and create a refund for it * Validate the refund * Close the session, and go to the picking of the session > Observation: The picking is not validated automatically. Why the fix: ------------ It was happening because the line that was put to 0 here (https://github.com/odoo/odoo/blob/eab97bed9c55a9057c7af7450ae1a09c6383a7b5/addons/point_of_sale/models/stock_picking.py#L249) has no lot assigned and should be deleted instead of just put to 0 quanity. It would then raise an error here (https://github.com/odoo/odoo/blob/2d933b83613ad52d76ab457201adecac6fcf184b/addons/stock_account/models/stock_move_line.py#L94) and cancel the validation of the picking. opw-4769042 Forward-Port-Of: odoo/odoo#224647 Forward-Port-Of: odoo/odoo#223888
Refunds for standard-cost inventory purchases now correctly reverse the related accounting entries instead of repeating the original bill balances. This helps keep stock valuation and purchase accounting accurate when products are returned and credited.
Original PR description
When users refund a real-time/standard cost product purchase, cogs lines are not reversed **Steps to reproduce** 1. Create a product category [CATEG]: - Costing Method: Standard - Inventory…
When users refund a real-time/standard cost product purchase, cogs lines are not reversed
**Steps to reproduce**
1. Create a product category [CATEG]:
- Costing Method: Standard
- Inventory Valuation: Automated
- Price Difference Account: 101403 Outstanding Payments (any account will do)
2. Create a product [PROD]
- Type: Storable
- Category: [CATEG]
3. Create and confirm a PO with [PROD]
4. Process the receipt
5. Create the bill
6. Issue the return and process it
7. Create the refund
**Issue**
The credit note cogs lines (price difference account and stock interim) have the same balance of the bill
However the credit note should mirror the original BILL with the opposite accounting entries.
This seems to occur because, when generating cogs lines, we take into account that the current move is a refund but then we use the move direction sign to alter the balance sign
opw-4845342
Forward-Port-Of: odoo/odoo#224873
Forward-Port-Of: odoo/odoo#221198This fix ensures that point-of-sale loyalty promotions calculate free product quantities correctly when multiple rewards are available. Customers and cashiers should see the right free items applied, reducing pricing mistakes and manual corrections.
Original PR description
Before this commit, when there were multiple reward lines for free products, adding a combination of those products would result in incorrect claimed free product quantities. opw-4975059 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224683 Forward-Port-Of: odoo/odoo#222780
Point of Sale now uses the currency's rounding precision when calculating combo child item prices, matching the Sales app behavior. This prevents small one-cent differences between the expected total and the POS total when product price precision differs from currency precision.
Original PR description
Currently, when you have a difference in precision between currency and product price, there can be a discrepency in the computation of the line prices, leading to a difference in the price total…
Currently, when you have a difference in precision between currency and product price, there can be a discrepency in the computation of the line prices, leading to a difference in the price total between the sale and pos app. Steps to reproduce: ------------------- * Modify the product precision to have 4 digits * Modify the burger menu combo product * Sale price 26.5 * Burger choice: Cheese burger, remove taxes, change price to 10 * Drinks choice: Coca cola, remove taxes, change price to 10, extra price set to 4.5 * Add another combo choice with 1 product only, no tax, price 10 * Open pos session * Add the combo, select the product that were modified > Total is 31.01 when it should be 31.00 Why the fix: ------------ Point of sale was using the decimal precision set on the product price to compute the price unit of the child lines. We can notice that the sale app was using the currency precision. We will use the same approach as sales. The decision was driven by the fact that 1) both scenarios could make sense, 2) total should be as set, 3) child line prices are not as important as the total and don't have a big influence. opw-4769227 Forward-Port-Of: odoo/odoo#224740 Forward-Port-Of: odoo/odoo#220352
This update prevents errors when users clear an end date on a time off request. It also ensures the correct working calendar is used when leave dates are changed after saving, improving accuracy for employees with changing schedules.
Original PR description
Bug 1 - traceback on removing end date
Steps to reproduce:
- open the time off request form
- remove the end date
Cause:
- bool comparison with date
Fix:
- add a check before using the request_date_from or request_date_to
Bug 2 - inappropriate resource calendar use
Steps to reproduce:
- Create two different version with different working calendar.
- now while creating leave record it uses correct resource calendar as per
request dates.
- but after saving the leave record, if try to change the request dates
it does not use correct resource calendar.
Cause:
- resource calendar compute method is not dependent on request dates.
Fix:
- updated the depends of compute method.
moreover refactored the method to improve the performance.
task-4965122
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix lets HR users update multiple employee versions tied to the same contract without triggering synchronization errors. It improves reliability when maintaining contract-related employee records and adds test coverage to prevent regressions.
Original PR description
Problem ---------- If you write on multiple versions with the same contract, the sync will not work and will raise errors Solution ---------- Change the behavior of the `write` to allow multiple write. 4 tests are added for that 1 removed because we don't want to allow merge of different contracts task-5030583
Point of Sale now applies product pricing rules in the right quantity order instead of relying on an internal record number. This helps ensure customers are charged the intended price when quantity-based pricelist rules are used.
Original PR description
Before this commit, the product pricelist items stored in IndexedDB were sorted by their `id`, which led to incorrect rule application in the PoS. When retrieving rules for a product, the order of rules matters. opw-4997926 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224687 Forward-Port-Of: odoo/odoo#222230
This fixes an accounting error when a dropshipped product is returned to an internal subcontracting location. The return now increases inventory value correctly, helping ensure stock valuation and interim accounts stay accurate for companies using automated valuation and Anglo-Saxon accounting.
Original PR description
…ml internal dropship return **Problem:** when the subcontracting setting is active, the return of a dropshipped product (not necessarily subcontracted) to the internal subcontracting location will…
…ml internal dropship return **Problem:** when the subcontracting setting is active, the return of a dropshipped product (not necessarily subcontracted) to the internal subcontracting location will create an account move that credits "stock valuation" instead of debitting it **Steps to reproduce:** - enable the "Anglo-Saxon Accounting","Multi-steps routes" and "Subcontracting" settings - create a storable product with dropshipping route and a vendor - in 'general information' write a non null cost - make sure the product category's inventory valuation' is 'automated' - create a new quotation for this product, confirm it and confirm the linked purchase order - click on the dropship smart button and validate the picking - click on return and select 'Physical Locations/Subcontracting Location' as the return location - validate and click on the valuation smart button - on the only stock valuation layer for this move, click on the book shaped widget **Current behavior:** the account move credits Stock Valuation and debits stock interim (received) **Expected behavior:** As we are returning the product to stock it should increase the value of the stock valuation account. Therefore, it should debit stock valuation and credit stock interim (received) **Cause of the issue:** If the mrp_subcontracting_dropshipping module is active, and if we call _is_dropshipped_return on a stock move which is the return (to the subcontracting location) of a dropshipped move : the method will return true. https://github.com/odoo/odoo/blob/b34cebcf0c142d92affdb642525f066d431b7ca3/addons/mrp_subcontracting_dropshipping/models/stock_move.py#L29-L35 Therefore, inside _account_entry_move, _is_in will be false (contrary to if mrp_subcontracting_dropshipping is not installed or if the destination is another internal location) https://github.com/odoo/odoo/blob/b34cebcf0c142d92affdb642525f066d431b7ca3/addons/stock_account/models/stock_move.py#L580 The aml vals will be computed inside _prepare_anglosaxon_account_move_vals https://github.com/odoo/odoo/blob/b34cebcf0c142d92affdb642525f066d431b7ca3/addons/stock_account/models/stock_move.py#L596 Here the fact the destination location is internal does not change the fact that it should debit the stock valuation account (meaning it should used acc_valuation as the second parameter of _prepare_account_move_vals) if the cost is positive. https://github.com/odoo/odoo/blob/b34cebcf0c142d92affdb642525f066d431b7ca3/addons/stock_account/models/stock_move.py#L610-L614 opw-4894755 Forward-Port-Of: odoo/odoo#224871 Forward-Port-Of: odoo/odoo#221009
This fix prevents Point of Sale order validation from getting stuck in an endless loading cycle. It ensures orders downloaded in PoS use the correct data retrieval path, improving reliability for cashier workflows and online payment scenarios.
Original PR description
*: pos_online_payment The `pos.order` model was missing from pohibitedAutoLoadedModels which was causing infinite loop when validating an order. This commit add this models to the pohibitedAutoLoadedModels variable. Now when downloading an order from the PoS the `read_pos_orders` method should be used, it will returns all related order data.
This fixes issues in the website form editor where conditional visibility settings could show partner ID numbers instead of names or fail to select a default condition. It also restores related automated test coverage so future changes are less likely to reintroduce the problem.
Original PR description
**Commit: 1** Steps to reproduce: 1. Add "To (Partners)" field in the form snippet. 2. Click on any other field and set visibility to "Visible only if". 3. Click on "To (Partners)". You will see a…
**Commit: 1** Steps to reproduce: 1. Add "To (Partners)" field in the form snippet. 2. Click on any other field and set visibility to "Visible only if". 3. Click on "To (Partners)". You will see a list of ids instead of partner names. Root cause: In FormOptionPlugin, the list of conditional visibility options is built from the option values. Since partners use ids as values, only ids were displayed. Fix: We added a conditional check to display the correct textContent. The condition is introduced by this commit https://github.com/odoo/odoo/commit/60f0cb8b979195905be118d3ee2817eac3948ffe **Commit: 2** Steps to reproduce: 1. Drop a form snippet and click on any field. 2. Change visibility from "Always visible" to "Visible only if". 3. Notice that no default comparator is selected. In previous versions, a default comparator was present. Issue: In `SetVisibilityAction.prepareConditionInputs`, the list of available fields for conditional visibility also includes hidden fields such as `email_to`. With the current logic, if the field name is not null, it is assigned as the default comparator. Since `email_to` is hidden, the default visibility condition is not set. Fix: By skipping hidden fields when preparing condition inputs so that only visible fields can be selected and used as the default comparator. The condition was introduced by commit https://github.com/odoo/odoo/commit/24a7112d7b85d045ffb0629f7feb6e5556e809a1 **Commit : 3** This commit re-enables the test_tour test, which was broken and skipped due to the DOM changes introduced by the new Website Builder. It also adapts the tour selectors accordingly.
This fixes a regression in the website builder where editing content that appears in multiple places on a page did not update all matching occurrences. Business users editing menus, category names, or related product/page fields should now see consistent changes across desktop and mobile views, reducing manual cleanup and publishing mistakes.
Original PR description
In the previous builder, the replication was done here: https://github.com/odoo/odoo/blob/b5f795de71e1a77fdc65aaed8a18ff2e92b67800/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js#L1263-L1356
The website editor color picker now uses semi-transparent default grayscale colors and gradients for image overlays, so backgrounds remain visible instead of being covered by solid colors. It also correctly shows when a default color has been selected, making editing more predictable for users.
Original PR description
*: html_builder, html_editor, web, website Previously, color filter default colors and gradients were set to 100% opacity, making them ineffective as overlays. This caused two issues: - Default colors didn't have the checkered transparency pattern in the color picker as in 18.3 - Fully opaque colors blocked the underlying image Steps to reproduce the original issue: 1. Open website and start editing 2. Drop any snippet with an image background and click on it 3. Click on the color filter option color picker The default colors and gradients appear solid and hide the background when applied. This commit introduces default 50% opacity to create functional semi-transparent overlays. As well as this, this PR fixes the problem when, after selecting the default color in the color picker, the color wasn't marked as selected. This PR follows [the html_builder refactoring]. [the html_builder refactoring]: odoo/odoo@9fe45e2b7ddb Related to task-4367641
Fixes a problem where saving a form could show a redirect warning that failed to open the right corrective action or include needed context. Users can now follow the warning from the save flow and be taken to the appropriate action to resolve the issue.
Original PR description
Have a web_save that raises a RedirectWarning which has the ID of an action and an additional context in its parameters. Trigger the warning in the form view by clicking on the save button in the form view. Before this commit, this feature did not work like at all. - The additional context was not taken into account - the path taken by clicking on the form's save button was not able to handle interacting with the main form view - The error dialog did not handle going into an action in target other than new After this commit, all this is fixed and the whole flow, that allow an error to be enriched such that the user could do the correct action to correct the error now works. opw-4742952 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#224620 Forward-Port-Of: odoo/odoo#223198
This fixes a live chat issue where customers could sometimes see a restart button after their conversation had already been forwarded to a human agent. Keeping the chatbot state consistent across browser tabs prevents confusing options from appearing during support conversations.
Original PR description
Before this commit, the restart button was sometimes shown after the conversation was forwarded to an agent which should not happen. This happens because the state of the chat bot is not sent on the bus, leading to inconsistent state. This commit ensures each step is sent on the bus to avoid inconsistencies. This commit also ensures the selected answer of a selection step is properly sent to every tab to avoid similar issues. task-5031990 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#223879
This fix restores the review summary shown in portal pages, so customers can see rating feedback where expected. It also updates related portal rating behavior and test coverage to help prevent the issue from returning.
Original PR description
*: portal_rating, rating, test_mail_full task-4853416 Forward-Port-Of: odoo/odoo#224415 Forward-Port-Of: odoo/odoo#216044
Razorpay return notifications sometimes include only confirmation identifiers, without amount or currency details. This fix lets those payments validate correctly, preventing checkout errors for affected eCommerce customers, especially on iPhone flows.
Original PR description
When processing notification data from the route `/payment/razorpay/return`, only three fields are available: `razorpay_payment_id`, `razorpay_order_id`, and `razorpay_signature`. See official source here: https://razorpay.com/docs/payments/payment-gateway/callback-url/#2-what-are-all-the-field-names-posted This fix prevents the error "The amount or currency is missing from the payment data." during validation, since neither amount nor currency are included in the notification payload. Steps to reproduce: - Setup Razorpay - Pay for a product on an eCommerce website from an iPhone - An error occurs due to missing amount and currency in the notification data. opw-4989944
This fixes an issue where users working in 12-hour time formats could select an afternoon time, such as 6 PM, but the field would save it as 6 AM. The date and time picker now correctly understands shortened AM/PM time entries, reducing scheduling mistakes for affected users.
Original PR description
Be in (or configure) a language with the 12 hour time format (i.e. such that times are displayed with am/pm). In a datetime field, open the datepicker and set the time in the afternoon (e.g. 6pm). Before this commit, the value that was actually set in the input was in the morning (6am in this case). The cause of the issue came from the date parsing. As we do not display the seconds in the input, the value was "06:00 pm", which couldn't be parsed properly. This commit fixes the issue by adding a step in parseDateTime, to try to parse with the short time format. opw~4996133 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#224936
The point of sale now calculates additional down payments on a sales order based on the remaining amount, not the original total. This prevents customers from being asked to overpay when making multiple deposits on the same order.
Original PR description
- Create a SO of 450 with 15% tax for a total of 517.50 - Create a first down payment from the POS of 10% => you pay 51.75 - Create a second down payment from the POS of 10% => we ask you to pay 51.75 again => We should ask him to pay 10% of 517.50 - 51.75 instead --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224223
Fixes an error that could occur when reloading fiscal localization settings after a related localization module was uninstalled in another session. This helps accounting users continue configuration work without needing to refresh or recover from a crash.
Original PR description
Currently, an error occurs when a user attempts to reload the fiscal localization after uninstalling the `l10n_syscohada` module. **Steps to Reproduce:** - Install l10n_cf module(with demo). - Switch…
Currently, an error occurs when a user attempts to reload the fiscal localization after uninstalling the `l10n_syscohada` module. **Steps to Reproduce:** - Install l10n_cf module(with demo). - Switch the company to `CF Company`. - Navigate to Invoicing settings - Login in different device with admin rights - In other device, uninstall l10n_syscohada module. - Now switch back to main device and do not reload the tab. - Click on Reload button under Fiscal Localization. **Error:** `TypeError: super(type, obj): obj must be an instance or subtype of type` **Root Cause:** since https://github.com/odoo/odoo/pull/186635/commits/58fb2db14ce3b7ddd70ffd617d2152c836151455, the line `self = self.env()['account.chart.template']` was removed from [1] when clicking the reload button, system tries create **data** at [2] but fails because the registry has been reset. [1]- https://github.com/odoo/odoo/blob/1dfa4cc9d259b4918424a07394938e24da8c643d/addons/account/models/chart_template.py#L183-L184 [2]- https://github.com/odoo/odoo/blob/c363014fe77d2ea706dabf8af232745d4e723267/addons/account/models/chart_template.py#L222 **Solution:** This commit prevents the error by providing new `env` with new `registry` to handle loading during the reload process. Sentry-**6272559266, 6750055374** Forward-Port-Of: odoo/odoo#216315
Tax return warning checks are now recalculated when a user opens them, so outdated warnings such as draft entries no longer remain after the underlying entries have been confirmed or deleted. This keeps the displayed check status accurate while avoiding extra load on the Tax Returns overview.
Original PR description
Before, when opening a Return that had bypassed checks such as Draft Entries, and we had deleted or confirmed those entries it wouldn't have refreshed the check number and would still display that there are draft entries. Now, we are forcing the check to be refreshed when someone wants to see them as to not crash the performances when someone opens the Tax Returns Kanban view. task-4850581 Forward-Port-Of: odoo/enterprise#90187
The Belgian point of sale integration now handles certain payment/security device errors more safely after sales data is sent. This reduces the risk of unexpected crashes for cashiers while a broader error-handling cleanup is planned.
Original PR description
Before this commit, it could happen that an error returned by the iot when contacting the blackbox was not correctly handled and led to a traceback. This commit solves the issue temporaly before finding a solution to harmonize the error handling in the blackbox. Forward-Port-Of: odoo/enterprise#93468
This fix prevents point-of-sale order validation from getting stuck in an endless loading cycle. It ensures downloaded PoS orders use the proper order-reading process so related order information is loaded safely and reliably.
Original PR description
*: pos_settle_due, pos_urban_piper The `pos.order` model was missing from pohibitedAutoLoadedModels which was causing infinite loop when validating an order. This commit add this models to the pohibitedAutoLoadedModels variable. Now when downloading an order from the PoS the `read_pos_orders` method should be used, it will returns all related order data.
Fixes a Documents app issue where uploading a file for an existing request or through the manage versions dialog created an extra card or list row for progress. The upload progress is now shown on the existing document, reducing confusion and keeping document views cleaner.
Original PR description
Step to reproduce: 1. Upload a file to a request: - Create a Request. - Upload a file for that request. - Another Kanban card / List row is created showing the upload progression. 2. Upload a file into the manage version dialog. - Manage version for an existing document. - Upload a new document. - Another Kanban card / List row is created showing the upload progression. The upload progression should be shown on the existing document. Task-4863051 Forward-Port-Of: odoo/enterprise#87428
Odoo Studio now correctly keeps fields visible and editable when the Technical Features group is selected for field visibility. This prevents fields from unexpectedly disappearing during Studio customization and helps users manage advanced visibility settings more reliably.
Original PR description
Steps to reproduce ================== - In debug mode - Go to Contacts - Open any record - Open studio - Click on any field - Add the "Extra rights / Technical Features" group to "Allow visibility to…
Steps to reproduce ================== - In debug mode - Go to Contacts - Open any record - Open studio - Click on any field - Add the "Extra rights / Technical Features" group to "Allow visibility to groups" => The group is not displayed as a tag - Restore the view - Now without debug mode (?debug=0), repeat the same steps => The field disappears, we need to toggle "Show Invisible Elements" to see it again Cause of the issue ================== https://github.com/odoo/odoo/pull/179354/commits/15aeaf88c268f047b8b83a5aa66f5da246c2b675 When calling get_views, the "base.group_no_one" is removed from the groups attribute and "invisible" is set to true if we are in debug mode. Solution ======== Adding "base.group_no_one" is still the way to have the expected behavior for now. We override some ir.ui.view functions when in studio to be able to edit it. According to the docstring of _postprocess_debug_to_cache, this feature is temporary. Another solution will be needed in the future. opw-4969262 Forward-Port-Of: odoo/enterprise#93435 Forward-Port-Of: odoo/enterprise#91647
Blackbox devices now keep their existing setup when they are unplugged and plugged back in, even if the system assigns a different connection port. This prevents duplicate device records and avoids losing the configuration businesses rely on for IoT operations.
Original PR description
Before this commit, if a blackbox was unplugged and re-plugged, and it was assigned a different serial port by the Raspberry Pi, it would show up as a new device in the database meaning the existing…
Before this commit, if a blackbox was unplugged and re-plugged, and it was assigned a different serial port by the Raspberry Pi, it would show up as a new device in the database meaning the existing configuration wouldn't work. After this commit, we handle the blackbox as a special case, and if the name of the device matches exactly with our existing blackbox, we update its identifier instead of creating a new device. This does require a new device specific check in the controller which is quite ugly. Another approach would have been to make the identifier of the blackbox equal its FDM ID instead of the serial port, but this was not done for the following reasons: - Changing the identifier format in stable would cause all existing clients' blackboxes to become unconfigured once their IoT box restarts. - Making the identifier different to the serial port would require a hack in the blackbox driver to change its own identifier and update the devices dictionary, since the serial interface assumes all devices use the port as their identifier. task-5055027 Forward-Port-Of: odoo/enterprise#93593
Fixed an issue that could cause the Tax Report to fail when its root report was changed to another report type, such as the Balance Sheet. This helps accounting users access tax reports without server errors in affected configurations.
Original PR description
**[FIX] account_reports: ensure join on account_move for tax report base amount calculation** Fixes a server error in the generic tax report where `account_move_line__move_id` was referenced without an explicit join. The fix adds a conditional join on `account_move` to make fields like `always_tax_exigible` available, preventing `UndefinedTable` during SQL execution. Steps to reproduce: 1 - in a fresh db or runbot go to `Accounting > Config > Accounting Reports`. 2 - Open the Tax Report and change the `Root Report` to Balance Sheet. 3 - Save and try to open the tax report. opw-4990771 Forward-Port-Of: odoo/enterprise#91941
Rental orders and their planning slots now stay synchronized when dates or shifts change, preventing mismatches and incorrect planning totals. Online shoppers also see more accurate rental availability based on their selected dates, improving booking reliability.
11 changes
Enhancements to existing features
Module upgrade processing now uses less memory when handling large website view data. This helps prevent database access failures during upgrades, improving reliability for affected customers.
Original PR description
### Issue A user cannot access their database (Bad Gateway) after trying to upgrade a module. ### Analysis The root cause is the out of memory error, stemming from the SQL query fetching all `arch_db` and then fetching them with `fetchall`. ### Solution This commit optimizes the loading of module terms in the `ir_module_module` model by iterating over the rows per chunks. This change reduces the memory footprint, which is crucial when dealing with heavy `arch_db` in the `ir_ui_view` table. We also filter out `if not generic_arch_db` directly in the SQL query instead of on the Python side. After applying this patch, there is no more `MemoryError` and the user can access their database. ### References opw-5014922 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224709 Forward-Port-Of: odoo/odoo#223439
Creating records with HTML content now avoids repeating an expensive cleanup step, which makes large email and marketing batches run much faster. This reduces processing time and memory use, especially for mass mailing campaigns with many recipients.
Original PR description
Description ----------- When creating records with `vals` for HTML fields, there are two 'sanitization' operations happening: 1) Once in `convert_to_column`, when converting the `vals` for *database*…
Description ----------- When creating records with `vals` for HTML fields, there are two 'sanitization' operations happening: 1) Once in `convert_to_column`, when converting the `vals` for *database* insertion 2) Once post-insert in `convert_to_cache`, when converting the `vals` for insertion in the *cache* for the newly created records. This redundancy has a negative performance impact when creating many records where new HTML fields are set, e.g., mass-mailing, as potentially large HTML documents are parsed and validated, often with external libraries. To address this issue, this commit removes the insertion into *cache* of the HTML values for the newly created records. This removes the overhead of the second sanitization, speeding up the creation, and also helps with overall memory pressure, as we're not inserting large HTML fields into cache. The latter is particularly noticeable for long-running batch creation processes that do *not* commit intermediate results. The downside of this patch is the potential *cache-miss* (and therefore the subsequent *query*) if the HTML field of the newly created records is read. This is unlikely in business code because intrinsically, an HTML field is often just a data 'blob' that has no logical usage. In the rare case where it needs to be read after creation, since the value in the database is already sanitized, re-sanitization is not necessary for insertion in the cache. Given these considerations, the trade-off seems reasonable to make. Benchmark --------- In a scenario for a marketing campaign with 1000 recipients, using a *mid-sized* email template and emulating a typical campaign, the results were: | Method | Before | After | Speed up | |-------------------------------|----------|-----------|----------| | `_process_mass_mailing_queue` | 2.84 min | 1.55 min | 1.8x | | `create` | 2.11 min | 50.23 sec | 2.5x | This represents roughly a *2x* performance improvement in processing an email campaign. * more detailed benchmarks are available in the task's description Reference --------- task-4962646 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224534 Forward-Port-Of: odoo/odoo#223875
Resolved issues and error corrections
Users can now find taxes even when they type only part of the tax name or an approximate shortcut. This makes tax selection faster and reduces failed searches when the exact tax label is not known.
Original PR description
Issue: - Searching for a tax by its name is not flexible. - Users have to type the exact name of a tax to find it. Fix: - Override the 'search' function in the 'Many2XTaxTagsAutocomplete' component Impact: - Improves user experience by allowing tax searches using partial or approximate name inputs. - For example, typing '21s' will return all relevant results like '21% S' and similar matches. Task: 5046098
Refunds for standard-cost purchased products now reverse the related cost accounting entries correctly. This prevents credit notes from duplicating the original bill balances and helps keep inventory and accounting reports accurate.
Original PR description
When users refund a real-time/standard cost product purchase, cogs lines are not reversed **Steps to reproduce** 1. Create a product category [CATEG]: - Costing Method: Standard - Inventory…
When users refund a real-time/standard cost product purchase, cogs lines are not reversed
**Steps to reproduce**
1. Create a product category [CATEG]:
- Costing Method: Standard
- Inventory Valuation: Automated
- Price Difference Account: 101403 Outstanding Payments (any account will do)
2. Create a product [PROD]
- Type: Storable
- Category: [CATEG]
3. Create and confirm a PO with [PROD]
4. Process the receipt
5. Create the bill
6. Issue the return and process it
7. Create the refund
**Issue**
The credit note cogs lines (price difference account and stock interim) have the same balance of the bill
However the credit note should mirror the original BILL with the opposite accounting entries.
This seems to occur because, when generating cogs lines, we take into account that the current move is a refund but then we use the move direction sign to alter the balance sign
opw-4845342
Forward-Port-Of: odoo/odoo#224873
Forward-Port-Of: odoo/odoo#221198This fixes inventory valuation when manufactured products are unbuilt after costs have changed. Instead of forcing the unbuild to reuse the original manufacturing cost, Odoo now records a corrective accounting entry so product costs and stock valuation stay aligned.
Original PR description
**Current behavior:** Since https://github.com/odoo/odoo/commit/84dda968146d2f3743ab7fc516300e50780725e3, we valuate an unbuild operation by attempting to match the ensuing OUT layer with the IN…
**Current behavior:** Since https://github.com/odoo/odoo/commit/84dda968146d2f3743ab7fc516300e50780725e3, we valuate an unbuild operation by attempting to match the ensuing OUT layer with the IN layer from the original MO. The point being to eliminate a potential valuation imbalance for the manufactured product (might affect cost, etc.). **New behavior** Don't attempt to match an unbuild valuation layer with the original MO valuation layer. If there is some cost difference between build time and unbuild time, make a corrective journal entry for it. **Issue with current behavior** The following sequence: 1. Create Product A with average costing, real-time valuation 2. Create 2 components, avg costing, real-time val 3. Create a BoM for Product A with the components 4. Manufacture 3 units of Product A with different component quantities (can set flexible consumption on BoM) 5. Unbuild the first manufactured unit Results in Product A's cost not matching the expected average cost according to the valuation layers. **Cause of the issue:** Unbuilding the first MO created an out move at the original "build time" cost, but since we've built 2 additional qty, that original cost is not the current average cost- thus the "theoretically current" standard price of the product (sum of layers value divided by remaining qty) is no longer the value we see on the product form. **Fix:** Don't try and match the valuation layers. Aside from issues such as the one described above, it might not actually make functional sense to do so (e.g., FIFO isn't actually adhering to first-in-first-out if we're preferring the original IN layer for an unbuild valuation). Instead we make a journal entry with any excess cost of production (it was actually a solution proposed in the discussion on https://github.com/odoo/odoo/commit/84dda968146d2f3743ab7fc516300e50780725e3 in the first place). Additionally, now that we aren't doing this mapping, we can revert the non-test difference of https://github.com/odoo/odoo/commit/3a69456a291da593748475c86e7efc6234019e47, as this commit was fixing an issue introduced by the change which added the mapping. opw-[4877597](https://www.odoo.com/web#id=4877597&view_type=form&model=project.task) Forward-Port-Of: odoo/odoo#222014 Forward-Port-Of: odoo/odoo#221718
Fixes an issue where reloading fiscal localization settings could fail after a related localization module was uninstalled in another session. This helps accounting administrators continue setup or maintenance without encountering an unexpected error.
Original PR description
Currently, an error occurs when a user attempts to reload the fiscal localization after uninstalling the `l10n_syscohada` module. **Steps to Reproduce:** - Install l10n_cf module(with demo). - Switch…
Currently, an error occurs when a user attempts to reload the fiscal localization after uninstalling the `l10n_syscohada` module. **Steps to Reproduce:** - Install l10n_cf module(with demo). - Switch the company to `CF Company`. - Navigate to Invoicing settings - Login in different device with admin rights - In other device, uninstall l10n_syscohada module. - Now switch back to main device and do not reload the tab. - Click on Reload button under Fiscal Localization. **Error:** `TypeError: super(type, obj): obj must be an instance or subtype of type` **Root Cause:** since https://github.com/odoo/odoo/pull/186635/commits/58fb2db14ce3b7ddd70ffd617d2152c836151455, the line `self = self.env()['account.chart.template']` was removed from [1] when clicking the reload button, system tries create **data** at [2] but fails because the registry has been reset. [1]- https://github.com/odoo/odoo/blob/1dfa4cc9d259b4918424a07394938e24da8c643d/addons/account/models/chart_template.py#L183-L184 [2]- https://github.com/odoo/odoo/blob/c363014fe77d2ea706dabf8af232745d4e723267/addons/account/models/chart_template.py#L222 **Solution:** This commit prevents the error by providing new `env` with new `registry` to handle loading during the reload process. Sentry-**6272559266, 6750055374** Forward-Port-Of: odoo/odoo#216315
The self-ordering flow now displays combo products with variants set to always be created in the same way as the main Point of Sale. This prevents customers from missing available combo choices and helps keep ordering behavior consistent across POS channels.
Original PR description
Issue: The products that had a variant creation set to "always" was not displayed like in the pos. (see task) This commit fixes issue by applying the same display logic as used in the POS, introduced in PR: https://github.com/odoo/odoo/pull/222252 Task-5005158 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
Odoo Sign now blocks unsupported encrypted PDF files before users try to complete signing. This prevents a confusing system error and helps users understand earlier when a document cannot be processed.
Original PR description
Currently an error occurs when signing an encrypted file with empty password. **Steps to replicate** * Install `Sign` * Sign> Upload a pdf > Add following…
Currently an error occurs when signing an encrypted file with empty password. **Steps to replicate** * Install `Sign` * Sign> Upload a pdf > Add following [pdf](https://drive.google.com/file/d/1M0_VzWLzv-lSZ-IlI9Zmx-M7jFGvtJJj/view?usp=sharing)> Sign the document using `Sign now` * Validate and send completed document `AttributeError: 'NoneType' object has no attribute 'seek'` **Cause:** This occurs because [1] returns `None` to the variable `output` at [2] which in turn passes the `None` value to [3] causing the error. Error occurs in python 3.12+, because it does not throw an exception in `_check_pdf_data_validity`. **Solution:** * Add a validation to prevent upload of unsupported files. [1]: https://github.com/odoo/enterprise/blob/e7861f1ddef2fb9628eebca93942e64c73cc95fc/sign/models/sign_document.py#L242-L243 [2]: https://github.com/odoo/enterprise/blob/e7861f1ddef2fb9628eebca93942e64c73cc95fc/sign/models/sign_completed_document.py#L33-L34 [3]: https://github.com/odoo/odoo/blob/033c7a63bdf3d10d9d2c5084959fd34f52011bea/odoo/tools/pdf/signature.py#L51 **Sentry-6784800544,6802557168**
This fixes an issue that could cause the generic tax report to fail after changing its root report setting. Accounting users can now open the tax report without encountering a server error in this scenario.
Original PR description
**[FIX] account_reports: ensure join on account_move for tax report base amount calculation** Fixes a server error in the generic tax report where `account_move_line__move_id` was referenced without an explicit join. The fix adds a conditional join on `account_move` to make fields like `always_tax_exigible` available, preventing `UndefinedTable` during SQL execution. Steps to reproduce: 1 - in a fresh db or runbot go to `Accounting > Config > Accounting Reports`. 2 - Open the Tax Report and change the `Root Report` to Balance Sheet. 3 - Save and try to open the tax report. opw-4990771 Forward-Port-Of: odoo/enterprise#91941
Fixed an issue where uploading a file for an existing document or request created a separate temporary card or row to show progress. The progress indicator now appears on the relevant existing document, making uploads clearer and avoiding duplicate-looking entries.
Original PR description
Step to reproduce: 1. Upload a file to a request: - Create a Request. - Upload a file for that request. - Another Kanban card / List row is created showing the upload progression. 2. Upload a file into the manage version dialog. - Manage version for an existing document. - Upload a new document. - Another Kanban card / List row is created showing the upload progression. The upload progression should be shown on the existing document. Task-4863051 Forward-Port-Of: odoo/enterprise#87428
Blackbox devices now keep their existing configuration when they are unplugged and reconnected with a different port assigned by the Raspberry Pi. This prevents duplicate device records and avoids disrupting configured IoT setups after reconnects.
Original PR description
Before this commit, if a blackbox was unplugged and re-plugged, and it was assigned a different serial port by the Raspberry Pi, it would show up as a new device in the database meaning the existing…
Before this commit, if a blackbox was unplugged and re-plugged, and it was assigned a different serial port by the Raspberry Pi, it would show up as a new device in the database meaning the existing configuration wouldn't work. After this commit, we handle the blackbox as a special case, and if the name of the device matches exactly with our existing blackbox, we update its identifier instead of creating a new device. This does require a new device specific check in the controller which is quite ugly. Another approach would have been to make the identifier of the blackbox equal its FDM ID instead of the serial port, but this was not done for the following reasons: - Changing the identifier format in stable would cause all existing clients' blackboxes to become unconfigured once their IoT box restarts. - Making the identifier different to the serial port would require a hack in the blackbox driver to change its own identifier and update the devices dictionary, since the serial interface assumes all devices use the port as their identifier. task-5055027 Forward-Port-Of: odoo/enterprise#93593
28 changes
New functionality added to Odoo
Payroll salary rules can now use domain-based conditions, making it easier to apply rules only when specific employee or contract criteria are met. This gives payroll teams more precise control over calculations and supports localized payroll setups such as French employee categories.
Basic AI capabilities can now be used without installing the full AI app, while advanced configuration remains available through a separate AI app. This gives users easier access to simple AI features and keeps deeper setup options organized for teams that need them.
Original PR description
We want people to be able to use basic AI features "for free" without installing the app by splitting the `ai` module into two. - `ai` module exposes all the features but the app icon is hidden which means that configuration is very limited. We allow users to specify their own llm api keys but that's it. Any `ai` model records isn't accessible to the UI. - `ai_app` exposes the views for the ai models. This allows users to configure their database regarding any AI features. TASK-ID: 5028645
Enhancements to existing features
The website editing experience now opens new content options from a dropdown instead of a modal window. This makes creating website content quicker and less disruptive for users working in Website, Appointments, and product barcode lookup flows.
Original PR description
task-2941442
Manual invoices for post-paid subscriptions now cover the full subscription period instead of only the partial skipped period, making billing easier to understand. Users are warned when creating these advance invoices, and salespeople are alerted when work or deliveries are completed after a period has already been invoiced.
Original PR description
_*= sale_subscription_stock, project_sale_subscription, sale_subscription_timesheet ### Before - Manually invoicing a post-paid sub before its next invoice date would generate an invoice only for the…
_*= sale_subscription_stock, project_sale_subscription,
sale_subscription_timesheet
### Before
- Manually invoicing a post-paid sub before its next invoice date would generate an invoice only for the skipped period (from last invoice to today).
- Users found this behavior unclear, especially when it is shown that the invoice period ended on the same day as it started.
- There was no warning for the users during this process
### After
- The full subscription period is now invoiced when manually creating an invoice for a post paid subscription.
- A warning is shown in the invoice creation wizard to notify users about post-paid subscriptions being invoiced in advance.
- An activity is posted for the salesperson when a delivery order, timesheet,or a milestone is completed for a closed period.
### Impact
- Users gain clarity when manually invoicing post-paid subscriptions.
- Reduces confusion during manual operations.
- Salesperson is notified if something is delivered after invoicing of a closed period.
---
task- 4929802The monthly planning calendar now shows shift times and job titles on separate lines, making schedules easier to scan. Long event names are shortened neatly, and popovers are simplified by removing remaining-hours details.
Original PR description
- Displayed time and title on separate lines for better readability. - Added ellipsis to truncate long event names. - Removed the remaining hours from the popover display. ``` Before: • 8 AM - 12 P... Shipping ... Now: • 8 AM - 12 PM (04:00) Shipping Associate ``` task-4672875
Sales reports and customer portal views now follow the newer section and subsection behavior across affected regional and subscription flows. This improves consistency for displayed subtotals and hidden grouped lines, reducing confusion in customer-facing documents.
Original PR description
- Community introduced a new section/subsection logic in odoo/odoo#221574, including support for hiding sections in report/portal. - Some localizations (e.g., l10n_br_sale and l10n_br_sale_subscription) were not yet adapted to these changes. - This commit updates these localizations to ensure consistency with community behavior by: - Supporting subtotals on section lines. - Grouping hidden section lines by tax_ids. See Also: https://github.com/odoo/odoo/pull/224219 task-5009037
Annual leave management for UAE payroll is now configured through Payroll settings instead of standard leave types. This makes payroll setup clearer and stops automatically calculating total annual leave days, giving businesses more direct control over the configured allowance.
Original PR description
Removed Annual Leave type from leave types and added it in Payroll settings, total leave days per year are not computed anymore Task: 5048791
Audit report PDFs now use the same page format across account reports and article pages. This reduces layout misalignment and makes printed or on-screen reports cleaner and easier to read.
Original PR description
Currently, account reports and article pages use different page dimensions. This inconsistency causes misalignment and often leads to irregular layouts when printed. To resolve this, we enforce a single paperformat for all generated PDFs and disable custom margin settings (see: `specific_paperformat_args`). This ensures every report uses a consistent page size, improving readability on screen and producing cleaner, more reliable printouts. Task-4989809
SEPA payment batch booking is now disabled by default in the affected payment modules, encouraging customers to use reconciliation based on end-to-end payment references. The field tooltip was also clarified so users better understand the business impact of enabling batch booking.
Original PR description
This commit has 2 main purposes: 1. Adapt the tooltip of batch booking fields present in both sepa modules for something more meaningful for our customers. 2. Change the default value of these field to false. The goald of this change is trying to change the "normal" behavior of our customers to let them use the new reconciliation feature based on the end to end uuid. To use this new feature, payments couldn't be batch booked. no task id
Documents now record clearer activity updates when files move between folders, are sent to or restored from trash, or are affected by access-right changes. This gives users and administrators better visibility into important document changes without needing to manually investigate what happened.
Original PR description
First commit :
[IMP] documents: add tracking messages to folder when moving documents
We are adding tracking (not really) messages to the old folders when moving documents in/out to/from another folder. We also add a tracking message when sending and restoring documents to/from trash.
Second commit :
[IMP] documents: add tracking on every documents impacted by rights change
This commits handles the tracking of Documents access rights by creating manually the tracking values from all the childrens documents/folders. All those tracking values are stored temporarily in a new table and will be processed by a cron as soon as possible.
Third commit :
[IMP] documents: adapt testsSpreadsheet users can now review and edit how a data source matches global filters directly from the data source panel. This reduces repetitive navigation, makes setup faster, and lowers the risk of missed or incorrect filter matching when adding pivots or other data sources.
Original PR description
Let's say you insert a new data source (e.g. a pivot data source) into an existing spreadsheet which have lots of global filters. You want to match your new pivot to each filter (or you want to check the automatic matching). Currently, you have to open each and every global filter configuration panel, uncollapse the "Field matching" section and check your pivot matching. This is a lot of clicks, and error prone if you have lots of filters. This commit adds the ability to see (and edit) in one place all matching of a given data source. Task-4344293
Users can now open spreadsheet dashboards directly in edit mode from the form view menu and from dashboard cards on mobile. This removes extra navigation steps and makes dashboard updates faster, especially for users working on phones or tablets.
Original PR description
### **PR Description** **Description of the issue/feature this PR addresses:** * In the **form view**, the cog menu did not provide an option to open dashboards in edit mode. * In the **mobile kanban view**, dashboard cards lacked an 'Edit' button, forcing users to switch context to edit dashboards. **Current behavior before PR:** * The cog menu in the form view has no 'Edit' option. * Dashboard kanban cards in mobile view have no 'Edit' button. * Users cannot directly open dashboards in edit mode from these views. **Desired behavior after PR is merged:** * Adds an 'Edit' option to the **cog menu** in the form view of `spreadsheet.dashboard`. * Adds an 'Edit' button to **kanban cards** for `dashboard_ids` in mobile view. * Clicking either option opens the selected dashboard in edit mode through the spreadsheet client. **Task:** [4965595](https://www.odoo.com/odoo/project/2328/tasks/4965595)
Companies based in Turkey can now print a Certificate of Employment directly from an employee record. This makes it easier for HR teams to issue official employment documentation without manual preparation.
Original PR description
### Before - N/A ### After - If an employee belongs to a company based in Turkey, a Certificate of Employment can now be issued to the employee. - This option is available under the cog menu>print>Certificate of Employment Task: 4910315
Point of Sale users can now switch the IoT Box connection mode directly from the local, online, or offline status button. This makes it easier to recover or choose the best connection method, including forcing websocket mode when needed.
Original PR description
We used to allow longpolling again manually if the IoT Box was reachable (by pinging it), but we couldn't force the connection to use websocket if needed. We now switch between modes when clicking the local/online/offline button in PoS. Task: 5055024 Forward-Port-Of: odoo/enterprise#93595
Printed planning schedules now use a clearer one-week calendar layout grouped by resources instead of a simple list table. This makes shared schedules easier to read and more useful for teams reviewing staffing and assignments.
Original PR description
[IMP] Planning: Print shiny plannings In this commit: - The simple table printed from planning list view is replace with a better one week calendar view grouped by resources. task-3349893
Employees who do not have Odoo user access can now open their salary offers through secure URL tokens, similar to applicants. Offer emails are also clearer when there is no expiration date, avoiding confusing empty expiry text.
Original PR description
Currently, when an offer is sent to an existing employee, they can't open it unless they have a user. However, not all employees in a company are granted user rights. Now, offers made to employees without users, just like those made to applicants, can be accessed via url tokens. Task-4914401
Indian payroll now supports additional contract fields that calculate salary components as percentages of wage, basic pay, or gross pay. This helps ensure related allowances and deductions adjust consistently when unpaid leave affects an employee's monthly payslip.
Original PR description
To make salary computation easier, add new contract fields based on the Indian salary structure. Percentage fields are used for calculate amount with leaves if employee has leave in his payslip month all other amount should decrease according to the calculation of basic and gross. EXA: 50000 monthly wage basic 50% of wage = 25000 hra 50% of basic = 12500 with 1 leave in month basic would be less than 25000 so based on basic we should calculate other salary components like HRA, LTA, STD, etc. task-4922359
The Workcenter Planning view now automatically groups work orders by the employee assigned to them. This makes it easier for managers to see workload by person and organize production tasks more efficiently.
Original PR description
- Users found it difficult to efficiently manage work orders in the Workcenter Planning view based on the employees assigned to them. There was no immediate way to view work orders categorized by responsible employee. - After this commit, A Group by Assigned Employee filter is now applied in the Workcenter Planning view. This allows users to instantly see work orders organized per employee, simplifying work-center management and improving overall usability. Task Id: 4900235
Resolved issues and error corrections
Subscription orders that include one-time products now correctly create a delivery and generate the related invoice. This prevents fulfillment from being missed when customers buy one-off items as part of a subscription order.
Original PR description
**Version:** - saas-18.4 **Steps to reproduce:** - Install the sale_subscription_stock module. - Create a one-time product and save it. - Create a subscription order, add the one-time product to the order line, and confirm the order. **Before this commit:** - When a one-time product was added to a subscription order, no delivery was created. **After this commit:** - A delivery is properly created, and an invoice is automatically generated when the order includes a one-time product. **Solution:** Add a condition to check for one-time products in the order lines and create a delivery if found. **Impact:** - A delivery is now created when a one-time product is in the sale order. Also, an invoice is automatically generated for it. task-4938898 Forward-Port-Of: odoo/enterprise#90528
Closing an AI Livechat conversation no longer opens a separate chat window with the ended conversation. This removes a confusing interruption for website visitors and keeps the AI chat close action behaving as expected.
Original PR description
closing the chat with the ai agent on the ai_livechat snippet results in a chatwindow popping up which gives a bad user experience. Steps to reproduce: - Log in as Mitchell Admin. - Go to website. -…
closing the chat with the ai agent on the ai_livechat snippet results in a chatwindow popping up which gives a bad user experience. Steps to reproduce: - Log in as Mitchell Admin. - Go to website. - Click on edit and choose `Contact & Forms`. - Add the AI Livechat website snippet. - From the snippet options, add an AI Agent and choose a livechat team. Make sure that Mitchell Admin is configured as an operator for that livechat team (livechat channel). - Click on save. - Open an incognito tab. Log in as Marc Demo. - Go to Website. - Type a message inside the `ASK AI` text area and press enter. - Wait until you receive a response and then click close. - A chat window will popup with the messages of the conversation with the AI along with a message saying `Visitor has left the channel`. This happens because `close` button will call `closeConversation` => `livechatService.leave()` => `visitor_leave_session` => `_close_livechat_session` that posts a message that the visitor has left the channel. This commit solves the issue by posting the message that the visitor has left the channel while suppressing the notification, if the operator of the channel isn't a human, to prevent the chatwindow from popping up. See https://github.com/odoo/odoo/pull/224758
When users upload a file to an existing document or request, the progress indicator now appears on that same item instead of creating a duplicate card or row. This reduces confusion and keeps document lists cleaner during uploads.
Original PR description
Step to reproduce: 1. Upload a file to a request: - Create a Request. - Upload a file for that request. - Another Kanban card / List row is created showing the upload progression. 2. Upload a file into the manage version dialog. - Manage version for an existing document. - Upload a new document. - Another Kanban card / List row is created showing the upload progression. The upload progression should be shown on the existing document. Task-4863051 Forward-Port-Of: odoo/enterprise#87428
This fix prevents a server error when opening the Tax Report after changing its root report setting. It ensures the report can access the needed accounting data reliably, so users can continue reviewing tax information without interruption.
Original PR description
**[FIX] account_reports: ensure join on account_move for tax report base amount calculation** Fixes a server error in the generic tax report where `account_move_line__move_id` was referenced without an explicit join. The fix adds a conditional join on `account_move` to make fields like `always_tax_exigible` available, preventing `UndefinedTable` during SQL execution. Steps to reproduce: 1 - in a fresh db or runbot go to `Accounting > Config > Accounting Reports`. 2 - Open the Tax Report and change the `Root Report` to Balance Sheet. 3 - Save and try to open the tax report. opw-4990771 Forward-Port-Of: odoo/enterprise#91941
Users assigned to a secondary company could hit an access error when creating multi-company tax returns. This fix allows eligible users to create those returns without being blocked, improving reliability for multi-company accounting workflows.
Original PR description
When a tax return is created with multi companies and a user member of one of the secondary companies, he would get an access error due to missing sudo() task-5039551 Forward-Port-Of: odoo/enterprise#93325
Dutch tax report submissions will now have their status checked automatically on a regular schedule instead of relying only on manual triggering during submission. This prevents reports from getting stuck without updates if a previous status check fails or crashes.
Original PR description
The way the cron was used before was by manually triggering it from the Tax Report submission flow. The cron was set to not never trigger otherwise (9999 months). However, if, for whatever reason, the cron fails/crashes, the status of the submitted report would never be fetched unless a report is submitted again.
Audit balance filtering now excludes draft entries, so users see accurate account balances for the selected period. Slovenian reporting deadlines are also set correctly across all companies, preventing missing defaults in multi-company setups.
This update fixes issues in the Documents app where moving folders by drag and drop could crash and creating a folder from the New menu could place it in the wrong location. It also simplifies internal folder handling, making folder organization more dependable for users.
Original PR description
1. Fix a crash when drag and dropping folders in the searchpanel 2. Fix creating a folder with New > Folder in any location 3. REF: Remove `is_company_root_folder` field, a simple getter can do the job. See details in individual commits. Follow-ups of #89030. Task-5055163
Features or functions removed from Odoo
This change removes an older way to create multiple planning shifts from a template because the same capability is now handled by a broader, shared implementation. This reduces duplication and keeps the shift creation process simpler and easier to maintain.
Original PR description
- This commit reverts https://github.com/odoo/enterprise/commit/84a5c06cca26628d29e2db64a661db542d3eca4c, which added the multiple shift creation feature. - The feature has since been implemented in a generic way in https://github.com/odoo/enterprise/pull/89560 keeping both implementations would introduce redundancy and add unnecessary complexity to the shift creation flow. task-5025754
The eCommerce dashboard menu has been removed because the underlying dashboard is no longer available. This keeps the website sales interface cleaner and prevents users from seeing a menu item that no longer leads to an active dashboard.
Original PR description
Description: - Drop website.menu_website_dashboard as the ecommerce dashboard is removed. SEE ALSO: Upgrade PR: https://github.com/odoo/upgrade/pull/8320 Community PR:https://github.com/odoo/odoo/pull/223724 task-4855511
13 changes
New functionality added to Odoo
When a cashier searches for a customer in Point of Sale and no match is found, the Create form now carries over the search text automatically. This saves time and reduces retyping by placing the text in the right field, such as name or phone, and focusing it for quick completion.
Original PR description
If a user searches for a partner and no match is found, clicking "Create" will now automatically transfer the search term into the appropriate field (name or phone) in the creation form. The matched input is also auto-focused. Task-4991076
Enhancements to existing features
Temporary timeout issues when submitting Indian e-invoices through MasterGST are now treated as warnings instead of blocking errors. This prevents invoices from getting stuck and lets scheduled background jobs retry them automatically.
Original PR description
Before this commit: --- while requesting for E-invoice on MasterGST, If there was a ConnectionTimeout on the IAP server the response was treated as an error. This caused invoices to enter an error state and prevented them from being retried by cron. In this commit: --- Timeout errors are treated as warnings by setting blocking_level to "warning" for "timeout" error codes. This allows cron jobs to automatically retry such invoices. task-4970444 Forward-Port-Of: odoo/odoo#221185
UAE payroll now better supports payslips for employees whose contracts are based on attendance or planning schedules. This helps ensure salary calculations match actual working arrangements and includes added test coverage for these scenarios.
Original PR description
Updates for the salary rules to accomodate Attendance and Planning-based contracts and test cases for said scenarios opw-[4873312](https://www.odoo.com/odoo/all-tasks/4873312)
Accounting reports grouped by account code now also show the matching account name for the current company. This makes consolidated multi-company reporting easier to read when several accounts are mapped to the same code.
Original PR description
In the current consolidation, you can make multi-company accounts and assign a code for each company. But a code must be unique inside each company. So it is not designed to map multiple accounts from a second company into one account of a first company. It is actually possible to achieve that effect by not making the accounts of the second company belong to the first company, and still make the code mapping. So you can make several accounts from the second company, map to the same code for the first company. Thus grouping by account codes become interesting for the accounting reports, in order to get a view of that consolidation. In order to make this reporting more clear, the name of the account corresponding to the account code (in the current company) is now shown when grouping by account code. task-4801891
Resolved issues and error corrections
Refunds for standard-cost purchased products now correctly reverse the original cost accounting entries. This prevents credit notes from overstating balances and keeps inventory and purchase accounting aligned after returns.
Original PR description
When users refund a real-time/standard cost product purchase, cogs lines are not reversed
**Steps to reproduce**
1. Create a product category [CATEG]:
- Costing Method: Standard
- Inventory Valuation: Automated
- Price Difference Account: 101403 Outstanding Payments (any account will do)
2. Create a product [PROD]
- Type: Storable
- Category: [CATEG]
3. Create and confirm a PO with [PROD]
4. Process the receipt
5. Create the bill
6. Issue the return and process it
7. Create the refund
**Issue**
The credit note cogs lines (price difference account and stock interim) have the same balance of the bill
However the credit note should mirror the original BILL with the opposite accounting entries.
This seems to occur because, when generating cogs lines, we take into account that the current move is a refund but then we use the move direction sign to alter the balance sign
opw-4845342
Forward-Port-Of: odoo/odoo#221198Italian electronic invoice exports now omit payment information where it should not appear and place supplier invoice references in the correct section. This helps companies using Italy localization produce XML files that better match official tax authority requirements and reduces rejection or compliance risk.
Original PR description
1- `<DatiPagamento>` shouldn't be included in autofatture. 2- The supplier's original invoice number and date must be placed in the `<DatiFattureCollegate>`, using `<IdDocumento>` and `<DataDocumento>` fields respectively. Currently `<IdDocumento>` is added to the `<DatiOrdineAcquisto>`. A fix is made to add `<IdDocumento>` and `<DataDocumento>` to `<DatiFattureCollegate>`. references: https://www.agenziaentrate.gov.it/portale/documents/d/guest/guida_compilazione-fe-esterometro-v1-10_aprile_2025 opw-4810326
Incoming invoice emails sent to a company journal alias are no longer rejected just because the sender's user account cannot access that company. This helps ensure supplier invoices and similar documents are created reliably from email, matching the behavior for unknown senders.
Original PR description
To reproduce the bug: 1- Create a DB with two companies and accounting app 2- Create a user and allow it to access company 2 3- Send a email using the user email to alias from purchase journal alias of company 2 4- The email will be rejected 5- Send a email using a random email address to alias. 6- The email will be accepted and an account.move is created. In a normal flow, when a user associated to the email not exists, the user_id is set to odoobot, otherwise, the user accosiated to the email. In the buggy flow the bug happens because `_compute_company_id` in account_move model, will set `company_id` to empty when user has no access to the company, as a result the `account_move` will fail. opw-4853027 Forward-Port-Of: odoo/odoo#217322
Point of Sale orders that skip the receipt screen are now still sent to the preparation display. This prevents kitchen or preparation teams from missing invoiced orders when automatic receipt printing is enabled.
Original PR description
Steps to reproduce: ------------------- - Enable "Automatic Receipt Printing" - Make a PoS order, with "Invoiced" checked, and validate it -> Observe that the command is not sent to the preparation display. Reason: ------- When skipping the receipt screen, we don't call `checkPreparationStateAndSentOrderInPreparation`, which then doesn't send the new command to the preparation display. The fix: -------- Backporting 26425ab712a3269beec98722 but without any refactoring. opw-5000406
Analytic plans are now processed from parent to child during project app installation. This prevents setup failures when a plan depends on a parent plan that has not yet been prepared, improving reliability for companies using hierarchical analytic plans.
Original PR description
When installing the `project` module, `_sync_plan_column(self, model)` is called for all existing analytic plans. The method iterates through `self` in arbitrary order, which means a child plan can…
When installing the `project` module, `_sync_plan_column(self, model)` is called for all existing analytic plans. The method iterates through `self` in arbitrary order, which means a child plan can be processed before its parent. In such a case, the code tries to create a related field pointing to a parent-level column that does not yet exist, leading to errors like: `Field name "x_plan26_id" unknown for related field "x_plan26_id.plan_id"` This happened because `self` was iterated without guaranteeing that parents are processed first. As a result, the related field chain (`.plan_id.parent_id...`) could reference missing intermediate fields. The fix is ordering the recordset by `parent_path`. Steps to reproduce: 1. In Odoo Inspector, search for model `account.analytic.plan`. and go to records. 2. Create a first plan. 3. Create a second plan and set the first plan as its parent. 4. Install the `project` app (triggers `_sync_plan_column`). 5. Observe the crash due to an unknown related field. OPW-5006494 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an issue where barcode transfers could incorrectly merge lot-tracked kit component lines with the same component added separately. This prevents unnecessary backorders when warehouse staff scan and validate the correct quantities.
Original PR description
**Problem:** when the components of a kit are tracked by lot, and that a picking is made of the components of a kit (exploded from the kit) and separatly one of the components on its own: if we open…
**Problem:** when the components of a kit are tracked by lot, and that a picking is made of the components of a kit (exploded from the kit) and separatly one of the components on its own: if we open the picking in barcode, the line of the component separated and line of the components of the kit are grouped, which leads to an unwanted backorder creation when validating **Steps to reproduce:** - create two products tracked by lot (comp A and comp B) - set an on hand quantity for both - create a storable product (final product) and create a BOM - in the BOM add comp A and comp B - create an internal transfer for 1 final product and 1 comp B - click on "mark as todo" - open this transfer in barcode, we see that the two lines from the comp B are grouped - scan the source location, click on +1 and +2 button to fulfill the quantities and validate **Current behavior:** a backorder is created **Expected behavior:** no backorder should be created as we entered the right quantities of the picking **Cause of the issue:** the lines from comp B should not have been grouped in the barcode picking. When doing the same scenario but with product not tracked those lines are not grouped opw-4998766
This fixes an error that blocked users from posting several invoices at once when using Avalara Brazil automatic tax mapping. Businesses can now process batches of these invoices without needing to post each one individually or encountering a system traceback.
Original PR description
Issue:
When posting multiple invoices with Avalara Brazil tax mapping, a traceback is raised:
ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: account.move
Only occurs when fiscal position is set to:
Automatic Tax Mapping (Avalara Brazil)
Affected versions:
- 17.0 and later
Steps to reproduce:
1. Set Avalara connection
2. Create an invoice with fiscal position: Automatic Tax Mapping (Avalara Brazil)
3. Duplicate that invoice
4. Select two or more invoices in draft
5. Try to post those entries
https://drive.google.com/file/d/1_CjX9vGhr-ZyUegP9QhOdQ--bfA8ylsH/view?usp=sharing
Current behavior:
- Error is raised: ValueError: Expected singleton
Expected behavior:
- Invoices should post correctly without errors
Forward-Port-Of: odoo/enterprise#93272The Malaysia Statement of Account report now applies the correct currency conversion when invoices are issued in a foreign currency. This prevents balances from being shown with the company currency symbol but the unconverted foreign amount, improving accuracy for customer reporting and receivables review.
Original PR description
## Short functional explanation of the error When we create an invoice with a different currency than the main one, the Statement of Account PDF report in aged receivable has an error. The amount for…
## Short functional explanation of the error When we create an invoice with a different currency than the main one, the Statement of Account PDF report in aged receivable has an error. The amount for each line is displayed as the main currency, but the conversion isn't done. For instance, if we create an invoice line of 3.5$ but our main currency is the Euro, in the report, it will show 3.5€ instead of 2.99€ ## Reproduction Steps 1. In a db without demo data, Download the app l10n_my. 2. In the general settings, click on Currencies. Activate a second currency and set its currency rate (relative to the main currency of the company) different of 1. 3. In accounting > settings, click on -> Currencies. Activate this second currency. 4. Click on configuration > journals and activate the debug mode. In the Journal Entries tab, as Currency, select a different currency than your main one (set in the general settings). 5. Create an invoice. Set a customer and select the journal for which you set an additional currency. Select this additional currency. Finally, add a product and click confirm. 6. Click on Reporting > Aged Receivable. Then, click on the line corresponding to your partner on Statement of Account. A PDF should download. ### Expected behavior The lines under Balance should be displayed as the main currency of the company, with the correct currency rates applying. ### Unexpected behavior The lines under Balance are displayed as the main currency of the company but the currency rates are not applying. ## Origin of the issue In the code, the currency rate isn't used to generate this line of the report: https://github.com/odoo/enterprise/blob/79c1ba68d48e7e068104d867e186610dd5110cc4/l10n_my_reports/report/statement_account_templates.xml#L52 __ opw-4975540 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website generation flow now reliably stops its background status checks when users leave or the screen is closed early. This prevents unnecessary server calls and avoids crashes that could interrupt the website creation experience.
Original PR description
In a component lifecycle, it may happen that onWillStart is called but not onWillUnmount. Indeed, if the component is destroyed before being mounted (because the current rendering has been cancelled), onWillUnmount isn't called. As a consequence, in the WebsiteGenerator component, the setInverval might never been called, thus producing an orm call every 10 seconds, when the component is destroyed. These calls lead to crashes ("Component is destroyed").
The solution is to use the onWillDestroy hook instead, which is always called.