Daily updates from Odoo
Tuesday, October 28, 2025
106 changes
19 changes
Enhancements to existing features
The Spanish localization now includes more detailed IGIC tax data for the Canary Islands, separating purchase taxes for goods and services and adding DUA-related taxes. This helps businesses apply the right tax mappings depending on the type of purchase and aligns Canary Islands handling more closely with mainland Spanish tax workflows.
Original PR description
We have splitted purchase taxes in goods and services because there are different mappings according to the scope. It has a similar functionality with spanish mainland taxes @jco-odoo There are doubts with the fiscal position `fp_nacional_canary_ns` as it is applied automatically to spanish non canarian partners but it should be similar to non-EU partners IMO. However, I think that the opinion fo some canary people would be nice to clarify it @Christian-RB --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230964 Forward-Port-Of: odoo/odoo#228667
Resolved issues and error corrections
This fix prevents users from adding tax tags to journal items dated before the tax lock date. It helps ensure locked tax reports cannot be changed unintentionally after a reporting period is closed.
Original PR description
Despite the tax lock date, users are able to modify the tax report by adding tags.
**Steps to reproduce:**
Ensure the tax lock date is set
1. Journal Items list view
2. Edit one/many lines that
- have a date before the tax lock date,
- don't have a tax,
- nor tax tags,
- and is not a tax line.
3. Add a new tax tag
**Issue:**
The tax tags are added and might impact a tax report, when you should have received a user error.
**Cause:**
The `write` function calls the `_check_tax_lock_date` which in turn only checks the existing line instead of the values given in the `write` parameters. Since the line has no existing tax tags the check does not fail.
**Solution:**
Call the tax lock check both before and after writing the move line.
Task-5169152
Forward-Port-Of: odoo/odoo#233032
Forward-Port-Of: odoo/odoo#232380Fixed a point of sale issue where selecting details within an order line could make the numpad open and immediately close. Cashiers can now use the numpad reliably when working with order line details such as eWallet balances.
Original PR description
Steps to reproduce: =================== - Click on an orderline - Then click on a detail inside it (e.g., eWallet Balance line) - The numpad first opens and then closes right away Issue: ====== - Clicking on a detail inside the orderline makes the numpad open and close at the same time - This makes it impossible to use the numpad properly Cause: ====== - The click from the child element also reaches the main orderline click - Because of this, the numpad gets two clicks (open and close) Fix: ==== - Added `stopPropagation` in the click handler to block event bubbling - Now the numpad only reacts once and stays open as expected Task: 5000327 Forward-Port-Of: odoo/odoo#232197 Forward-Port-Of: odoo/odoo#227675
Creating invoices from multiple sales orders now keeps orders with different fiscal positions on separate draft invoices. This prevents incorrect tax or account calculations caused by combining orders that must follow different fiscal rules.
Original PR description
Problem: When a user selects multiple sale orders from the list view to create invoices, if the selected orders have different fiscal positions, they are all incorrectly merged into a single draft…
Problem: When a user selects multiple sale orders from the list view to create invoices, if the selected orders have different fiscal positions, they are all incorrectly merged into a single draft invoice. An invoice can only have one fiscal position. This merging causes unexpected behavior, as the accounts and taxes are computed based on the single (and potentially incorrect) fiscal position of the final invoice, rather than the respective fiscal positions of the originating SOs. Solution: This commit modifies the 'Create Invoices' action to group the selected sale orders by their `fiscal_position_id`. It will now create as many separate draft invoices as there are unique fiscal positions among the selected orders. task: 5188965 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#233119 Forward-Port-Of: odoo/odoo#232821
Repair service products that are published for sale now show up correctly in the website shop. This fixes a visibility issue that prevented customers from finding and buying services configured to create repair orders.
Original PR description
Steps to reproduce: ------------------------- 1. Install repair and website_sale modules 2. Create a product that is the service type 3. Configure a product to create a repair order when the product…
Steps to reproduce: ------------------------- 1. Install repair and website_sale modules 2. Create a product that is the service type 3. Configure a product to create a repair order when the product is ordered 4. Publish the product from the Sales tab 5. Open the website without being signed in 6. Search for that product Observation: ------------------------- The product is not visible on the website shop. Issue: ------------------------- The method `_get_saleable_tracking_types(self)` is used to determine which product service tracking types are considered saleable on the website. However, this method was not defined for repair products, causing them to be excluded from the domain used to fetch saleable products. https://github.com/odoo/odoo/blob/b0203ae02d472bd7522bc21971f0e659766eaffe/addons/website_sale/models/website.py#L301-L308 Solution: ------------------------- Define the `_get_saleable_tracking_types(self)` method for repair products so they are properly included in website listings. opw-5102204 Forward-Port-Of: odoo/odoo#232154 Forward-Port-Of: odoo/odoo#231000
This fixes an issue where some browser pages could make Odoo mistakenly think the signed-in user had changed, causing real-time notification channels to be cleared. Users should now keep receiving their own presence updates reliably, including when sessions are opened or closed in other browser windows.
Original PR description
The websocket worker holds a single WebSocket connection per browser. Clients pass the current user ID and DB name, which the worker uses to detect login/logout. Some pages omit the DB name, causing…
The websocket worker holds a single WebSocket connection per browser. Clients pass the current user ID and DB name, which the worker uses to detect login/logout. Some pages omit the DB name, causing the worker to incorrectly mark the user as changed. This clears previous channels, which may never be added back. This is particularly noticeable with presence channels: the user's own channel can be lost, preventing them from receiving their own presence updates (e.g. when another browser closes, the user cannot see they are disconnected and cannot correct the value). The user's own presence channel should be added server-side, so the first subscription immediately returns the user presence and the DB should not be taken into account if ommited. task-5096212 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#233182 Forward-Port-Of: odoo/odoo#232984
Bank reconciliation models now correctly apply label rules that exclude specific text, even when some transaction details are empty. This helps accounting teams rely on automated matching rules more consistently and reduces missed reconciliation matches.
Original PR description
Currently bank reconciliation model match only the label type “Contains” The “not contain” type is not working Steps to reproduce: - Open Accounting Dashboard - Access Bank journal reconciliation models (3dots > Models) - Open a [Model] and set: - Label "Not Contains" "Test" - Add a Bank Statement with any label Issue: [Model] won't match Analysis: This occurs because in case the payment_ref or transaction_details contains a NULL value the ILIKE operations will evaluate to NULL, not TRUE or FALSE. Any other comparison involving NULL value will result in NULL and the whole condition will fail opw-5065006 [Task link](https://www.odoo.com/odoo/project/49/tasks/5065006) Forward-Port-Of: odoo/enterprise#97745
Sale orders that use only fixed taxes can now be read through XML-RPC without serialization errors. This prevents integrations and external tools from failing when accessing orders or invoices with this tax setup.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a fixed tax; 2. create a sale order using only the fixed tax; 3. read the sale order via XML-RPC. Issue ----- TypeError: cannot marshal None unless allow_none is enabled Cause ----- If only a fixed tax is used, the `_get_tax_totals_summary` method returns a dict where the `display_base_amount_currency` and `display_base_amount` values are `None`, leading to an error serializing the result. Solution -------- As the result gets serialized by `OdooMarshaller(allow_none=False)`[^1], we should use `False` instead of `None`. [^1]: https://github.com/odoo/odoo/blob/b887bf2/odoo/addons/base/controllers/rpc.py#L114 opw-5173477 Forward-Port-Of: odoo/odoo#232955 Forward-Port-Of: odoo/odoo#232517
Creating a new warehouse could accidentally generate many duplicate replenishment routes when an existing global route had been renamed. This fix ensures Odoo reuses the intended route instead, keeping route lists clean and avoiding confusion for inventory teams.
Original PR description
In _find_or_create_global_route, use the asked 'route_name' instead of the potentially modified name of `data_route`. This ensures that if '_find_or_create_global_route' is called with the exact same values a new route will not be re-created. https://github.com/user-attachments/assets/815adf60-aa2d-4699-a79d-f9ad9607cbea ## How to reproduce (in runbot 17.0): - Enable "Multi-steps Routes" - Unarchive route "Replenish on Order (MTO)", change the name, set company to "My company (San Francisco)" - Go to "My Company (Chicago)" - Create new Warehouse => Check all the routes: ~100 MTO routes with the modified name have been created. OPW-5149842 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232829 Forward-Port-Of: odoo/odoo#232613
Batch invoice sending now alerts users when the required scheduled process is turned off, instead of failing silently. Administrators are guided to the relevant configuration so they can re-enable it, helping prevent missed invoice deliveries.
Original PR description
This commit raises a RedirectWarning to the cron configuration to inform the user that the batch invoice cron must be enabled. Batch invoices cannot be sent if cron is disabled. task-5122707 Current behavior before PR: If batch invoice send is called and cron is disabled, then it will silently fail and not send. Desired behavior after PR is merged: If batch invoice send is called and cron is disabled, then it will raise a RedirectWarning to the cron configuration. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229318
RFQs created from approvals now use the currency configured on the product's vendor instead of defaulting to the company's currency. This keeps purchase requests consistent with other RFQ creation flows and helps avoid pricing or currency mismatches when working with vendors.
Original PR description
Issue: When creating an RFQ from an approval, the created purchase order does not use the currency set on the vendor of the product. Rather, it uses the currency of the company, with the value converted based on the vendor's currency to get the price. This is not consistent with other ways we create RFQs, which all respect the vendor currency. Solution: Pass the vendor's currency into the values sent when creating the purchase order. In the case of modifying an existing purchase order, only modify purchase orders matching vendor's currency. opw-4549937 Forward-Port-Of: odoo/enterprise#97069
Contacts can no longer be deleted when they are already connected to point-of-sale orders. This preserves customer information on past sales records and prevents accidental loss of order history links.
Original PR description
Before this commit, it was possible to delete a contact record even if it was linked to PoS orders, which would cause it to be unlinked from those orders. opw-5164368 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231812 Forward-Port-Of: odoo/odoo#231442
UPS shipping labels could fail to generate in production when the sender or shipper did not have a VAT number set. This fix avoids sending an empty tax ID to UPS, so label creation can continue normally for affected shipments.
Original PR description
Only in production mode, if the sender or the shipper's VAT was not set, the UPS answer would be an error, preventing the label generation altogether. This is because we send an empty string if the VAT was not set, and UPS couldn't process it. Forward-Port-Of: odoo/enterprise#98227
The Documents details panel now consistently shows the email alias management section in list view when an alias is configured. This fixes a regression that could hide alias information and improves stability by ensuring the panel always receives the fields it needs.
Original PR description
Steps to Reproduce =================== 1. Set an alias in settings. 2. Go to a folder in Documents. 3. Open document right panel in list view. -> The email alias section in the document detail panel is missing in the list view. Issue ======= The commit [1] unintentionally change few lines of code in forward-port conflict. It removes `mail_alias_domain_count` from the view and we get undefined in JS. After this commit ================== Added required fields for the details panel to the controller mixin in JS to make it stable friendly and simplify usage regardless of view arch. Adapt selectors of `documents kanban: select a range with SHIFT key` test as we always pass `type` from js which groups documents into folder and file. [1] https://github.com/odoo/enterprise/commit/d278f9013113c6de4b3425fecad5d54a9d4d22b9 Task-5045288 Forward-Port-Of: odoo/enterprise#93401
A bug was fixed where some company accounting setups could fail during upgrades because a missing bank account prefix was handled incorrectly. The system now treats the missing value safely, helping affected localizations complete their accounting migration without interruption.
Original PR description
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False. ```traceback…
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False.
```traceback
module l10n_co: Running migration [$1.0] end-migrate_update_taxes
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 523, in load_modules
migrations.migrate_module(package, 'end')
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 222, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 259, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/odoo/18.0/addons/l10n_co/migrations/1.0/end-migrate_update_taxes.py", line 8, in migrate
env['account.chart.template'].try_loading('co', company)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 160, in try_loading
return self._load(template_code, company, install_demo, force_create)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 228, in _load
self._post_load_data(template_code, company, template_data)
File "/home/odoo/src/enterprise/18.0/account_reports/models/chart_template.py", line 10, in _post_load_data
super()._post_load_data(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 681, in _post_load_data
self._setup_utility_bank_accounts(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 845, in _setup_utility_bank_accounts
accounts = self.env['account.account']._load_records([
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5526, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5430, in _load_records_create
records = self.create(vals_list)
File "<decorator-gen-208>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 498, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/addons/account/models/account_account.py", line 997, in create
start_code = prefix.ljust(digits - 1, '0') + '1' if len(prefix) < digits else prefix
TypeError: object of type 'bool' has no len()
```
Databases affected by this traceback error:
https://upgrade.odoo.com/odoo/request/3191023/tbg/2150
task-5167397
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#232169This update makes tax calculations more predictable when preparing discounts, down payments, and future combo product flows. It fixes several edge cases where tax details could be reused or shaped incorrectly, reducing the risk of incorrect totals in sales and accounting documents.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232284
Refreshing a signature document no longer hides the key action buttons or replaces the document name with a generic label. This keeps the signing flow clear and reliable for users who reload the page while reviewing or signing documents.
Original PR description
Version: - 18.0 Steps to reproduce: - Open document which is send for signature. - Refresh the browser. Before: - Refreshing the page was hiding the `sign now` and `cancel` button from control panel…
Version: - 18.0 Steps to reproduce: - Open document which is send for signature. - Refresh the browser. Before: - Refreshing the page was hiding the `sign now` and `cancel` button from control panel and also the name of document get replaced by 'unnamed' in breadcrumbs - The `needToSign` value was loaded from the context and used later to show those button, which is only available when navigating from `go_to_document`. On refresh, the context was lost, leading to the error. - Breadcrumbs were not getting set properly on reload. After: - Added `needToSign` to the URL query string.On page refresh, the data is retrieved from the URL as a fallback instead of relying on the context. - Add name of document to URL query string and on page refresh use that name to get correct name of document and update name to breadcrumbs using `setDisplayName`. Impact: - Buttons remain visible after refresh. - Correct document name is shown in breadcrumbs. - Ensures a smoother and more stable user experience when viewing documents. task-4805166 Forward-Port-Of: odoo/enterprise#97837 Forward-Port-Of: odoo/enterprise#93589
Fixes an issue where website forms configured to send an email could fail on submission and log an error. The form builder now includes required hidden default values when the email action is selected, helping ensure visitor submissions are processed reliably.
Original PR description
Currently, an error occurs when submitting the 'Send Email' form. **Steps to Reproduce:** - Install the `website` module. - Go to `website` > `Click on Edit` > `Drag and drop form.` - Click the form…
Currently, an error occurs when submitting the 'Send Email' form. **Steps to Reproduce:** - Install the `website` module. - Go to `website` > `Click on Edit` > `Drag and drop form.` - Click the form and in actions select again `Send an E-mail` action and `save`. - `Submit the form`, and the error appears in the logs. **Error**: KeyError: 'website_form_signature' **Cause:** This error occurs when submitting the "Send Email" form from the website. When the user chooses the model Outgoing Mails (mail.mail), the email_to hidden field is not added. This is because email_to is only added when the recipient email value is changed from the sidebar via apply [1]. As a result, the email_to hidden field is missing from the form. And the website_form_signature is added from [2], but due to the condition at [3], the code at [2] is not executed. When it is accessed at [4], KeyError is raised. **FIX:** This commit ensures that when the user selects the action model, if there are hidden field , it is added to the form with its default value. [1]: https://github.com/odoo/odoo/blob/3b16debc6d6557334082fdf841b20ef0e31fc9d2/addons/website/static/src/builder/plugins/form/form_option_plugin.js#L863 [2]: https://github.com/odoo/odoo/blob/82639728f2bcb4e7786f120de2aeba3f5fbab209/addons/website/tools.py#L252 [3]: https://github.com/odoo/odoo/blob/82639728f2bcb4e7786f120de2aeba3f5fbab209/addons/website/tools.py#L236 [4]: https://github.com/odoo/odoo/blob/82639728f2bcb4e7786f120de2aeba3f5fbab209/addons/website/controllers/form.py#L88 sentry-6746753251 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes cases where parts of website and HTML editor content that should be editable were incorrectly treated as locked. It helps users edit intended sections more reliably in the website builder and related HTML editing tools.
Original PR description
[FIX] html_builder, *: set contenteditable attribute on correct elements *: html_editor, website The goal of this commit is to fix the behavior of the `extra_contenteditable_handlers` resource; its goal is to mark as editable an element that is inside an `.o_not_editable`. The problem is that this was not working as intended as the elements given as argument to the handler were a list that was filtered of the elements that have an `.o_not_editable` ancestor. Note: even if it is in stable, the `force_editable_selector` resource has been renamed as `content_editable_providers` as a provider is needed in some cases. Because it has become a provider, the `force_not_editable_selector` resource has also been renamed and becomes a provider. This choice has been made to maintain consistency throughout the plugin.
13 changes
Enhancements to existing features
VoIP searches now better match phone numbers even when they include spaces, hyphens, parentheses, or other formatting characters. This makes it easier for users to find contacts and call history entries using only the digits they remember.
Original PR description
Introduces the `matchPhoneNumber` function, a new utility designed to match search terms against fully formatted phone numbers. The function converts a digit string like "123" into a flexible regex (e.g., /1\D*2\D*3/i) that matches digits regardless of any non-digit characters (spaces, hyphens, parentheses) between them. **Example:** * **SearchTerms**: "123" * **Target**: "+1 (2)-345" * **Match**: "1 (2)-3" Task-5160296
Resolved issues and error corrections
Repair service products that are configured for online sale are now shown in the website shop and search results. This ensures customers can find and buy repair-related services online as intended, improving storefront accuracy and sales availability.
Original PR description
Steps to reproduce: ------------------------- 1. Install repair and website_sale modules 2. Create a product that is the service type 3. Configure a product to create a repair order when the product…
Steps to reproduce: ------------------------- 1. Install repair and website_sale modules 2. Create a product that is the service type 3. Configure a product to create a repair order when the product is ordered 4. Publish the product from the Sales tab 5. Open the website without being signed in 6. Search for that product Observation: ------------------------- The product is not visible on the website shop. Issue: ------------------------- The method `_get_saleable_tracking_types(self)` is used to determine which product service tracking types are considered saleable on the website. However, this method was not defined for repair products, causing them to be excluded from the domain used to fetch saleable products. https://github.com/odoo/odoo/blob/b0203ae02d472bd7522bc21971f0e659766eaffe/addons/website_sale/models/website.py#L301-L308 Solution: ------------------------- Define the `_get_saleable_tracking_types(self)` method for repair products so they are properly included in website listings. opw-5102204 Forward-Port-Of: odoo/odoo#231000
The Documents details panel now reliably shows the email alias management section in list view when an alias is configured. This restores access to folder email alias settings and prevents missing information caused by a previous update.
Original PR description
Steps to Reproduce =================== 1. Set an alias in settings. 2. Go to a folder in Documents. 3. Open document right panel in list view. -> The email alias section in the document detail panel is missing in the list view. Issue ======= The commit [1] unintentionally change few lines of code in forward-port conflict. It removes `mail_alias_domain_count` from the view and we get undefined in JS. After this commit ================== Added required fields for the details panel to the controller mixin in JS to make it stable friendly and simplify usage regardless of view arch. Adapt selectors of `documents kanban: select a range with SHIFT key` test as we always pass `type` from js which groups documents into folder and file. [1] https://github.com/odoo/enterprise/commit/d278f9013113c6de4b3425fecad5d54a9d4d22b9 Task-5045288
Refreshing a signature document no longer hides the Sign Now and Cancel buttons or replaces the document name with “unnamed.” This keeps the signing flow clearer and more reliable for users who reload the page while reviewing a document.
Original PR description
Version: - 18.0 Steps to reproduce: - Open document which is send for signature. - Refresh the browser. Before: - Refreshing the page was hiding the `sign now` and `cancel` button from control panel…
Version: - 18.0 Steps to reproduce: - Open document which is send for signature. - Refresh the browser. Before: - Refreshing the page was hiding the `sign now` and `cancel` button from control panel and also the name of document get replaced by 'unnamed' in breadcrumbs - The `needToSign` value was loaded from the context and used later to show those button, which is only available when navigating from `go_to_document`. On refresh, the context was lost, leading to the error. - Breadcrumbs were not getting set properly on reload. After: - Added `needToSign` to the URL query string.On page refresh, the data is retrieved from the URL as a fallback instead of relying on the context. - Add name of document to URL query string and on page refresh use that name to get correct name of document and update name to breadcrumbs using `setDisplayName`. Impact: - Buttons remain visible after refresh. - Correct document name is shown in breadcrumbs. - Ensures a smoother and more stable user experience when viewing documents. task-4805166 Forward-Port-Of: odoo/enterprise#93589
Creating invoices from multiple sales orders now keeps orders with different fiscal positions on separate draft invoices. This prevents tax and account calculations from being applied using the wrong fiscal setup, improving billing accuracy.
Original PR description
Problem: When a user selects multiple sale orders from the list view to create invoices, if the selected orders have different fiscal positions, they are all incorrectly merged into a single draft…
Problem: When a user selects multiple sale orders from the list view to create invoices, if the selected orders have different fiscal positions, they are all incorrectly merged into a single draft invoice. An invoice can only have one fiscal position. This merging causes unexpected behavior, as the accounts and taxes are computed based on the single (and potentially incorrect) fiscal position of the final invoice, rather than the respective fiscal positions of the originating SOs. Solution: This commit modifies the 'Create Invoices' action to group the selected sale orders by their `fiscal_position_id`. It will now create as many separate draft invoices as there are unique fiscal positions among the selected orders. task: 5188965 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#233119 Forward-Port-Of: odoo/odoo#232821
This fixes a problem where some company accounting setup or upgrade processes could fail when a bank account code prefix was left unset. The system now treats the missing prefix safely, helping affected databases complete accounting migrations without errors.
Original PR description
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False. ```traceback…
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False.
```traceback
module l10n_co: Running migration [$1.0] end-migrate_update_taxes
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 523, in load_modules
migrations.migrate_module(package, 'end')
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 222, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 259, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/odoo/18.0/addons/l10n_co/migrations/1.0/end-migrate_update_taxes.py", line 8, in migrate
env['account.chart.template'].try_loading('co', company)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 160, in try_loading
return self._load(template_code, company, install_demo, force_create)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 228, in _load
self._post_load_data(template_code, company, template_data)
File "/home/odoo/src/enterprise/18.0/account_reports/models/chart_template.py", line 10, in _post_load_data
super()._post_load_data(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 681, in _post_load_data
self._setup_utility_bank_accounts(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 845, in _setup_utility_bank_accounts
accounts = self.env['account.account']._load_records([
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5526, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5430, in _load_records_create
records = self.create(vals_list)
File "<decorator-gen-208>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 498, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/addons/account/models/account_account.py", line 997, in create
start_code = prefix.ljust(digits - 1, '0') + '1' if len(prefix) < digits else prefix
TypeError: object of type 'bool' has no len()
```
Databases affected by this traceback error:
https://upgrade.odoo.com/odoo/request/3191023/tbg/2150
task-5167397
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#232169Warehouse creation no longer creates many duplicate global replenishment routes when an existing route has been renamed for a company. This keeps inventory configuration cleaner and prevents confusing duplicate route records for users managing multiple warehouses or companies.
Original PR description
In _find_or_create_global_route, use the asked 'route_name' instead of the potentially modified name of `data_route`. This ensures that if '_find_or_create_global_route' is called with the exact same values a new route will not be re-created. https://github.com/user-attachments/assets/815adf60-aa2d-4699-a79d-f9ad9607cbea ## How to reproduce (in runbot 17.0): - Enable "Multi-steps Routes" - Unarchive route "Replenish on Order (MTO)", change the name, set company to "My company (San Francisco)" - Go to "My Company (Chicago)" - Create new Warehouse => Check all the routes: ~100 MTO routes with the modified name have been created. OPW-5149842 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232829 Forward-Port-Of: odoo/odoo#232613
Users now receive a clear warning when trying to send batch invoices while the required scheduled process is disabled. This prevents silent failures and helps administrators quickly enable the needed setting so invoices can be sent as expected.
Original PR description
This commit raises a RedirectWarning to the cron configuration to inform the user that the batch invoice cron must be enabled. Batch invoices cannot be sent if cron is disabled. task-5122707 Current behavior before PR: If batch invoice send is called and cron is disabled, then it will silently fail and not send. Desired behavior after PR is merged: If batch invoice send is called and cron is disabled, then it will raise a RedirectWarning to the cron configuration. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229318
Purchase requests created from approvals now use the currency configured for the product's vendor instead of defaulting to the company's currency. This keeps RFQs consistent with other purchasing flows and helps avoid currency mismatches or incorrect purchase order updates.
Original PR description
Issue: When creating an RFQ from an approval, the created purchase order does not use the currency set on the vendor of the product. Rather, it uses the currency of the company, with the value converted based on the vendor's currency to get the price. This is not consistent with other ways we create RFQs, which all respect the vendor currency. Solution: Pass the vendor's currency into the values sent when creating the purchase order. In the case of modifying an existing purchase order, only modify purchase orders matching vendor's currency. opw-4549937 Forward-Port-Of: odoo/enterprise#97069
This fixes a UPS shipping label issue where missing sender or shipper VAT details could block label creation in production. The change avoids sending an empty tax ID value that UPS rejects, helping businesses generate labels reliably even when VAT information is not available.
Original PR description
Only in production mode, if the sender or the shipper's VAT was not set, the UPS answer would be an error, preventing the label generation altogether. This is because we send an empty string if the VAT was not set, and UPS couldn't process it. Forward-Port-Of: odoo/enterprise#98227
Saudi e-invoicing checks now also run when a company has no country set, catching setup issues before documents are processed. This helps avoid errors that could stop scheduled EDI web service operations from running for affected companies.
Original PR description
ZATCA invoice misconfigurations are only checked for if the company has Saudi Arabia set as its country. However, ZATCA EDIs can be generated without Saudi Arabia set as the country. Thus, companies without a company set can create EDI documents for misconfigured invoices. This may cause traceback errors which prevent the "EDI : Perform web services operations" cron from running at all. This commit ensures that configuration checks are run on companies without countries set (and adds a relevant unit test). opw-5057792 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233078 Forward-Port-Of: odoo/odoo#231255
This fix improves work entry generation for employees who have different types of working schedules, including fully flexible schedules without a calendar. It helps ensure payroll and attendance-related entries are created using the right schedule and timezone, reducing incorrect or missing work entries.
Original PR description
- fix work entries generation for employees with different working schedules types - made work entries generation check for employee timezone in case the employee is fully flexible and doesn't have a calendar - added method `_get_calendar_at` to get the calendar of the resource at a given date - added `test_work_entry_different_calendars` for work entries generation for employees with contracts with different calendar types task-id: 5065160 Forward-Port-Of: odoo/odoo#232828 Forward-Port-Of: odoo/odoo#226641
Bank synchronization now avoids importing transactions on a company's accounting lock date, preventing entries and opening balances from being created with incorrect dates. This helps keep financial records consistent with locked-period rules and reduces reconciliation issues.
Original PR description
If you have a company with a lock date set, and you connect a bank that has transactions dated to the day of the lock date, these transactions will be fetched, which do not make sense because nothing…
If you have a company with a lock date set, and you connect a bank that has transactions dated to the day of the lock date, these transactions will be fetched, which do not make sense because nothing should be created in a period covered by a lock date. As a result, these transactions would be created at a wrong date (if the current month is the first after the lock date or if the sequence has a monthly reset, then they would be appended to the current month, else if the sequence reset annually, then they would be created at the current date). Additionally, the potential opening balance would be created at a wrong date too, since it would try to create it one day prior to the oldest transaction. The date which the opening balance is created would not be the same as the transactions above, which adds a layer to the mess created. To prevent this, at initialization, we set the last sync date one day after the lock date, not the same day. Finally, the test related to statement creation were adapted to this new behavior. Some ordering based on `date` in other tests were changed to `internal_index` to unify the test file with these changes. opw-4890538 Forward-Port-Of: odoo/enterprise#94648 Forward-Port-Of: odoo/enterprise#93543
7 changes
Resolved issues and error corrections
Refreshing a signature document no longer hides the Sign Now and Cancel buttons or replaces the document name with 'unnamed'. This keeps the signing flow clear and stable for users who reload the page.
Original PR description
Version: - 18.0 Steps to reproduce: - Open document which is send for signature. - Refresh the browser. Before: - Refreshing the page was hiding the `sign now` and `cancel` button from control panel…
Version: - 18.0 Steps to reproduce: - Open document which is send for signature. - Refresh the browser. Before: - Refreshing the page was hiding the `sign now` and `cancel` button from control panel and also the name of document get replaced by 'unnamed' in breadcrumbs - The `needToSign` value was loaded from the context and used later to show those button, which is only available when navigating from `go_to_document`. On refresh, the context was lost, leading to the error. - Breadcrumbs were not getting set properly on reload. After: - Added `needToSign` to the URL query string.On page refresh, the data is retrieved from the URL as a fallback instead of relying on the context. - Add name of document to URL query string and on page refresh use that name to get correct name of document and update name to breadcrumbs using `setDisplayName`. Impact: - Buttons remain visible after refresh. - Correct document name is shown in breadcrumbs. - Ensures a smoother and more stable user experience when viewing documents. task-4805166 Forward-Port-Of: odoo/enterprise#93589
RFQs created from approvals now use the currency configured for the product's vendor instead of defaulting to the company currency. This keeps purchasing documents consistent with other RFQ creation flows and helps avoid currency and price mismatches.
Original PR description
Issue: When creating an RFQ from an approval, the created purchase order does not use the currency set on the vendor of the product. Rather, it uses the currency of the company, with the value converted based on the vendor's currency to get the price. This is not consistent with other ways we create RFQs, which all respect the vendor currency. Solution: Pass the vendor's currency into the values sent when creating the purchase order. In the case of modifying an existing purchase order, only modify purchase orders matching vendor's currency. opw-4549937 Forward-Port-Of: odoo/enterprise#97069
This fixes Lithuanian payroll calculations so employees enrolled in pension accumulation are not charged the pension contribution twice. Payslips will now reflect the expected social security contribution, helping avoid payroll over-deductions and correction work.
Original PR description
**Issue**
When generating a payslip for an employee with the `l10n_lt_pension` setting enabled on the contract ("Participate to pension accumulation system"):
- the SSC is raised from 19.5% to 22.5%
- a 3% pension contribution ("Pension Scheme") is added This effectively doubles the expected contribution.
Various sources (e.g. https://taxsummaries.pwc.com/lithuania/individual/other-taxes) seem to show this is not correct.
opw-5067664
Forward-Port-Of: odoo/enterprise#95880This fix prevents UPS label generation from failing when sender or shipper VAT details are not provided. It avoids sending blank tax ID values that UPS rejects in production, helping deliveries continue without unnecessary errors.
Original PR description
Only in production mode, if the sender or the shipper's VAT was not set, the UPS answer would be an error, preventing the label generation altogether. This is because we send an empty string if the VAT was not set, and UPS couldn't process it. Forward-Port-Of: odoo/enterprise#98227
DHL pallet package defaults were corrected from millimeter-style values to the centimeter values DHL expects. This prevents delivery validation failures and allows shipping labels to be generated when users keep the default pallet dimensions.
Original PR description
## Short functional explanation of the error When setting the 'DHLxw Package Type' of a DHL delivery method to 'DHL pallets' without changing default values, trying to validate an order delivery…
## Short functional explanation of the error When setting the 'DHLxw Package Type' of a DHL delivery method to 'DHL pallets' without changing default values, trying to validate an order delivery causes an error. ## Reproduction Steps 1. Type 'Delivery method' in the dashboard. Select DHL BE, set the region to Europe and the 'DHLxw Package Type' to 'DHL pallets'. Click on the arrow at the right of 'DHL pallets'. You should see the default values set to 1200, 1600 and 1200. These correspond to millimeters, while DHL expects centimeters. 2. Make sure you're using a company located in Belgium. 3. In the inventory settings, make sure that either 'multi-step route' is unchecked or that for your warehouse, the outgoing shipments are set to '1 step'. 3. Create a new quotation. Select a Customer with a Belgian address. Add a product for which there's at least 1 copy in stock. 4. Click on add shipping and select DHL BE. Then click add and ok. 5. Click on confirm. A smart button at the top of the page called "delivery" should appear. Click on it and set the scheduled date to a future day. Finally, click validate. ### Expected behavior New labels should generate without issue. ### Unexpected behavior An error occurs: ```Bad request Multiple problems found, see Additional Details 1001: The requested product(s) (N) not available based on your search criteria.(687662d08999745d3df3783068fcca24) 410107: The piece height exceeds max, N/- 410304: No products available ``` ## Origin of the issue The default values for DHL are set to 1200, 1600 and 1200, which correspond to millimeters. However, DHL expects centimeters, for which the default value is thus too high. Note: because the issue stems from default values, after implementing the fix, the module should be reinstalled. __ opw-4804639
Assets created from vendor bills now calculate their original value using only the deductible portion of partially deductible lines. This prevents asset values from being overstated and improves accuracy in depreciation and accounting records.
Original PR description
We allow the user to create an asset from a bill with lines which are not fully deductible but the created asset's original value is the based on the entire balance of the journal item. It should be only the deductible part. task-5156256
This update restores the Swedish POS control that limits receipt reprints to one time, helping businesses stay compliant with local fiscal requirements. It also improves blackbox error handling so disconnected devices and driver issues are reported more reliably instead of causing endless loading or hidden errors.
Original PR description
Before this commit, the receipt reprint check logic (which only allows a receipt to be reprinted once) was not working. There were two issues preventing it from working: - The name of the function had changed but not been updated in this module, so the override was not applied. - The ID being used to check the order was incorrect. A few smaller issues were also fixed: - A logging issue in the IoT driver, which prevented the error severity from being printed. - An infinite loading UI if the blackbox was disconnected. - The blackbox error handler swallowing up some errors due to only expecting one specific format. Forward-Port-Of: odoo/enterprise#98152 Forward-Port-Of: odoo/enterprise#98076
14 changes
Enhancements to existing features
Users can now start the shortcut timer from the My Timesheet grid when it is grouped by task, parent task, or helpdesk ticket, in addition to project. This makes time tracking faster and more flexible for teams who organize work around tasks or support tickets.
Original PR description
_*= helpdesk_timesheet, timesheet_grid **Current behavior:** In the My Timesheet grid view, the shortcut timer can only be started when grouped by project. **New behavior:** The shortcut timer can now also be started when the grid view is grouped by task, parent task, or helpdesk ticket. task-3429443
Chat windows now use the same underlying conversation model as the main Discuss app. This should make messaging behavior more consistent across AI chat, live chat, website live chat, and WhatsApp integrations, reducing differences users may notice between channels.
Original PR description
PR community: https://github.com/odoo/odoo/pull/232493
Knowledge article trash notification emails now use a clearer standard layout with a direct button to open the article. Recipients are also told that trashed articles are permanently deleted after 30 days, while the person who moved the article to trash no longer receives an unnecessary notification.
Original PR description
This PR refines the existing notification email for trashed articles with the following changes: 1. Use the standard notification email layout (`mail_notification_layout`) with an access button, allowing the recipient to quickly open the trashed article. 2. Do not send a notification to the user who moved the article to the trash. 3. Include a short note in the email informing the recipient that the article will be permanently deleted after 30 days, and that they must take action if they wish to keep it. Additionally, this PR replaces all occurrence of "send to trash" with "move to trash" to match common UI terminology and improve clarity. Task-5095861
Belgian payroll now includes additional work entry types that were previously missing. This helps payroll teams classify employee time more accurately and supports more complete payroll processing.
Payroll users now receive a warning when closing a salary adjustment while related payslips are not yet finalized. This helps prevent confusion because the adjustment can still affect unfinished payslips, allowing users to review and act before payroll is completed.
Original PR description
When a salary adjustment is closed with related payslips still not done, salary adjustments are still applied. This commit adds a warning so that the user knows if this adjustment is closed to act accordingly task: 5135771
Turkey payroll benefits now use the newer salary rule-based flexible benefits setup instead of separate payslip input records. This keeps the localization aligned with the current payroll flow and makes benefit inputs appear in the expected payroll input section.
Original PR description
purpose: adapting the new system of flexible benefits coming from salary rules for tr localization - adapted the fields in `hr.version` to become salary rules with `condition_select` as `property_input` which makes it appear in the input section - removed the records in `hr.payslip.input.type` and converted them into corresponding salary rules - removed the inherited view of `hr.version` - changed the tests in `test_salary_rules` to use salary rules instead of hardcoded fields task-id: 5122400
Resolved issues and error corrections
This fix ensures Brazilian AvaTax users see the custom product list views needed to correct tax-related product data. It restores access to key Brazilian fields, inline editing, and product navigation, avoiding an unsuitable standard product list.
Original PR description
The actionable_errors widget was changed to ignore views if a view_mode key is present in the action [1]. It caused the standard product.product list view to pop up, which doesn't work in this case. The custom views have the relevant Brazilian fields (SPED type etc), can be edited inline, and have a "View" button allowing the user to go to the product form view. The standard view has none of these. [1] odoo/odoo@3bd833c73ea654d8558e3d9701ad41e4d75ddd6 opw-5154766 Forward-Port-Of: odoo/enterprise#98012
Invoices paid with a partial amount from the invoice payment widget will now stay marked as partially paid instead of being automatically closed with a write-off. This helps users keep control of small remaining balances and avoid unintended accounting adjustments.
Original PR description
Prevents the system from creating a write-off and marking an invoice as 'Fully Paid' when a partial payment (within tolerance) is reconciled from the invoice form. The invoice status will now correctly remain 'Partially Paid', giving the user control over the remaining balance. task-5114658 Forward-Port-Of: odoo/enterprise#95899
This update fixes issues in Colombian electronic invoicing where new vendor bills could miss their commercial status, repeated event submissions could block the process, and issuer acceptance events could be rejected by DIAN. This helps accounting teams process vendor bills and compliance events more reliably.
Original PR description
this commit solves following issues: - the commercial status was missing on newly created vendor bills - the flow got stuck when an event had already been sent and we tried to send it again - The accept by issuer event generated errors on DIAN's side task: 5064534 Forward-Port-Of: odoo/enterprise#95444
Fixed an issue where partially paid subscription upsell orders could show a down payment invoice amount of zero instead of the actual paid amount. This ensures customers and businesses see accurate invoiced amounts for partial online payments on upsell orders.
Original PR description
Version- 17.0 ### Issue: - When an upsell order is partially paid (e.g., 10% of the original amount), the generated downpayment invoice incorrectly displayed an invoiced amount of 0. ### Steps to reproduce: - Make an Upsell order of subscription. - Update the condition of Online Payment from 100% to 10% (in this case). - Make the payment of 10% from portal view. - The invoice amount will be shown as $0. ### Fix: - Updated `_get_subscription_qty_to_invoice` to correctly determine the invoiced quantity and amount for downpayment invoices on upsell orders. ### Impact: - The downpayment invoices for upsell orders now correctly reflect the actual invoiced amount. Forward-Port-Of: odoo/enterprise#97571 Forward-Port-Of: odoo/enterprise#96719
UPS shipping labels could fail to generate in production when a sender or shipper VAT number was not entered. This change avoids sending an empty tax ID to UPS, allowing labels to be created when VAT information is unavailable.
Original PR description
Only in production mode, if the sender or the shipper's VAT was not set, the UPS answer would be an error, preventing the label generation altogether. This is because we send an empty string if the VAT was not set, and UPS couldn't process it. Forward-Port-Of: odoo/enterprise#98227
Studio no longer allows users to set default values on fields that are defined as readonly. This prevents configuration choices that could cause inconsistent behavior or errors in business records where those defaults are not properly supported.
Original PR description
Before this commit, it was possible to set via Studio a default value for readonly fields. Functionally, this opened the floor for a variety of issues when the user set a default value that way on models that did not handle that (by providing a default in the Action or some other way) Decision has been made to remove that feature for fields defined in python as readonly. Task-5172619
Opening the invoicing dashboard no longer fails when Stripe card issuing is enabled but the company only has currencies unsupported by Stripe active. The system now avoids creating or selecting Stripe issuing journals unless a valid supported currency is available, improving reliability for localized company setups.
Original PR description
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. **Steps to…
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. **Steps to replicate:** * Install `account` without demo * Set Company currency to INR and deactivate USD in currencies. * Install `hr_expense_stripe` > Open Invoicing you will get the error. `ValueError: Expected singleton: res.currency()` **RootCause:** * When `hr_expense_stripe` is installed, the compute method [1] checks for supported currencies and defaults to USD if none are found. But since USD is often inactive by default in localized online databases, `stripe_currency_id` ends up empty . * Which causes [2] to pass an empty `stripe_currency_id` to [3], which expects at least one record, leading to the error. **Solution:** * Avoid creation of stripe issuance journal during installation when currency is not supported. * Add a constraint to check if stripe currency is valid for creating stripe issuance journal. * prevent creation and selection of journal for stripe issuing from settings. * [Reference Images](https://www.notion.so/Changes-in-Stripe-issuing-unsupported-vs-supported-2856722d865e803e8da1ece29cce7582?source=copy_link) for before and after functionality [1]: https://github.com/odoo/enterprise/blob/2ea15cc9c7c5f114b3786b256c64e269b3e3a313/hr_expense_stripe/models/res_company.py#L72 [2]: https://github.com/odoo/enterprise/blob/2ea15cc9c7c5f114b3786b256c64e269b3e3a313/hr_expense_stripe/models/account_journal.py#L52 [3]: https://github.com/odoo/odoo/blob/98bae80f57733162c67593539ef47dfd0c6d8797/odoo/addons/base/models/res_currency.py#L205 sentry-6916946380 Forward-Port-Of: odoo/enterprise#96271
Changing rental dates in the online cart now keeps the cart layout stable and preserves interactive quantity controls. This prevents shoppers from getting stuck when adjusting rental periods, improving checkout reliability.
Original PR description
Steps to reproduce: =================== 1. Add a meeting product to the cart with the "Rental" option checked. 2. Go to the cart and change the date range. → The cart layout shifts to the left, and…
Steps to reproduce: =================== 1. Add a meeting product to the cart with the "Rental" option checked. 2. Go to the cart and change the date range. → The cart layout shifts to the left, and quantity buttons become unclickable. Cause: ====== Two separate issues caused this behavior: 1. **Layout shift:** When updating the date range, `cart_quantity` can be undefined. The logic that determines whether to toggle the `col-lg-7` class relies on this value. When undefined, it incorrectly assumes the cart is empty and shifts the layout to the left. 2. **Unclickable buttons:** The following line replaces the entire `.js_cart_lines` element: https://github.com/odoo/odoo/blob/abf9bc083c5a219a0b6fc0346dcd2a2cb503e081/addons/website_sale/static/src/js/website_sale_utils.js#L88 This removes all old elements (and their event listeners) and inserts new ones from the server. As a result, interactive buttons (e.g., quantity update) lose their functionality. Older versions didn't face this issue because they used jQuery event delegation, which automatically handled dynamic elements. Solution: ========= 1. provide the cart_quantity value via the controller, 2. Restart the cart interaction after re-rendering to restore event bindings for clickable buttons. opw-5167866 Forward-Port-Of: odoo/enterprise#97715
31 changes
Enhancements to existing features
This update adds end-of-day balance reporting and refund support for Six payment terminals in Point of Sale. It also improves transaction speed, receipt handling, and payment details so store teams get a smoother checkout and closing process.
Original PR description
Based on the feedback received from our partners we are missing some features in our Six terminal integration. This PR adds them 1. Send balance command to print end-of-day report 2. Adapt the code to reduce the sleep delay after each transaction 3. Refunds/payment reversals for Six + it also adds some minor code improvements like a) Card brand is now saved in pos payments instead of the card number b) Card number is still being sent to PoS and while not stored in v17 will be stored from v18 c) The code of ctypes_terminal_driver and Six Driver was improved to reuse the buffer size and improve the buffer usage d) Fixes the receipt size for the Six terminals e) updates the Six C libraries used to the latest version to get all the newest fixes Related C PR: https://github.com/odoo/worldline-lib/pull/9 Forward-Port-Of: odoo/enterprise#98132 Forward-Port-Of: odoo/enterprise#96748
The HTML editor now handles format removal more consistently for headings and other block text. This helps users clean up styled text while preserving the intended base typography, reducing confusing formatting behavior when editing website or document content.
Original PR description
Description of the issue this PR addresses: Current behavior before PR: Styles applied via typography classes such as `display-1-fs`, `display-2-fs`, etc. could not be removed from block elements. eg: `<h1 class="display-1-fs">t[es]t</h1>`. Desired behavior after PR is merged: - HTML tags (`<p>`, `<h1>`, etc.) represent the base typography. - Typography classes (display-*) should be treated like equivalent HTML tags, not as removable styles. - Only display classes (*-fs) are considered for format removal. - When removing format, the editor now restores the font style of the underlying HTML tag. eg: `<h1 class="display-1-fs">t<span class="h1">[es]</span>t</h1>` task-4981275 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The HTML editor now handles inline code formatting more reliably, including wrapping selected text when the backtick key is pressed and supporting empty inline code blocks. This prevents cursor jumps and makes navigation around code-formatted text smoother for users editing content.
Original PR description
**Purpose of this PR:** This PR includes multiple fixes and improvements related to typing and navigating around inline code elements. **Current behavior before this PR:** - Because of the change…
**Purpose of this PR:**
This PR includes multiple fixes and improvements related to typing and navigating around inline code elements.
**Current behavior before this PR:**
- Because of the change made in commit [1], the selection was not set until two backticks were detected. As a result, inserting a single backtick caused the cursor position to change unexpectedly.
- Typing two backticks (``) without any text between them did not properly create an inline code element.
Desired behavior after this PR is merged:
- The text node is merged with its siblings only when two backtick are detected, so no DOM changes occur with a single backtick, and the selection no longer needs to be updated in that case.
- Now, a zws is added as a sibling of the inline code element to ensure proper navigation outside the code element.
- Typing two backticks with nothing in between now correctly creates an empty inline code element.
- Wrap the selected text in a inline code element when the '`' key is pressed.
- Replaced ZWS with feffs around and inside inline code elements.
This improves:
- feffs are now added on editor initialization (like links) and removed during cleanForSave.
- Arrow key navigation no longer skips characters at code boundaries.
- Empty inline code elements can properly hold the cursor(via mouse or arrow keys).
task: 4585706
[1]: https://github.com/odoo/odoo/commit/f792acf0bc66fb77e25bf8a0753c6a2f4284f0e8Resolved issues and error corrections
This fixes the Brazilian AvaTax product error workflow so users are shown the tailored product list again instead of a generic product list. The restored view includes Brazil-specific tax fields, inline editing, and an easy path to open product details, helping users resolve tax setup issues correctly.
Original PR description
The actionable_errors widget was changed to ignore views if a view_mode key is present in the action [1]. It caused the standard product.product list view to pop up, which doesn't work in this case. The custom views have the relevant Brazilian fields (SPED type etc), can be edited inline, and have a "View" button allowing the user to go to the product form view. The standard view has none of these. [1] odoo/odoo@3bd833c73ea654d8558e3d9701ad41e4d75ddd6 opw-5154766 Forward-Port-Of: odoo/enterprise#98012
Down payment invoices for subscription upsell orders now show the amount actually paid instead of incorrectly displaying zero. This helps customers and staff see accurate billing information when partial online payments are used.
Original PR description
Version- 17.0 ### Issue: - When an upsell order is partially paid (e.g., 10% of the original amount), the generated downpayment invoice incorrectly displayed an invoiced amount of 0. ### Steps to reproduce: - Make an Upsell order of subscription. - Update the condition of Online Payment from 100% to 10% (in this case). - Make the payment of 10% from portal view. - The invoice amount will be shown as $0. ### Fix: - Updated `_get_subscription_qty_to_invoice` to correctly determine the invoiced quantity and amount for downpayment invoices on upsell orders. ### Impact: - The downpayment invoices for upsell orders now correctly reflect the actual invoiced amount. Forward-Port-Of: odoo/enterprise#97571 Forward-Port-Of: odoo/enterprise#96719
This fixes an issue where validating a partial barcode transfer into another package could incorrectly fail with a missing lot or serial number error. Businesses using lot-valued inventory can now split packaged quantities more reliably without being blocked during warehouse validation.
Original PR description
**Problem:** With a valued by lot/SN product, assigning a partial barcode move line to a new package will trigger a lot error when validating even if there is a lot on the line. **Steps to…
**Problem:** With a valued by lot/SN product, assigning a partial barcode move line to a new package will trigger a lot error when validating even if there is a lot on the line. **Steps to reproduce:** - Create product tracked by lot and valued by lot/SN. - Set on on hand quantity of 100 in stock with a package that you create and a lot that you create. - Create an internal transfer for 100 of this product. - Mark it as to do. - Open it in barcode. - Scan stock. - Scan the package. - Edit the line to quantity of 50. - Scan any other empty package already existing to set it as the delivery package. - Validate. - On the incomplete transfer widget, also click on validate. **Current behavior:** An error 'Lot/Serial number is mandatory for product valuated by lot' is triggered even though there is a lot on the line. **Cause of the issue:** When _assignEmptyPackage() is called to assign the new package, it calls shouldsplitline() which returns true because line.qty_done is smaller thant line.reserved_uom_qty https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/stock_barcode/static/src/models/barcode_picking_model.js#L949-52 Therefore, splitLine() is called and a new line is created with no package and no lot. Then, when we validate, _action_done() is called on the move which calls _action_done() on the move lines. https://github.com/odoo/odoo/blob/30189db8a47e69038242a68706cfdfe6c152e779/addons/stock/models/stock_move.py#L2065 In the stock_account override, the error is raised for the line newly created because it has no lot_id and no lot_name. https://github.com/odoo/odoo/blob/30189db8a47e69038242a68706cfdfe6c152e779/addons/stock_account/models/stock_move_line.py#L90-L91 opw-5028008 Forward-Port-Of: odoo/odoo#233129 Forward-Port-Of: odoo/odoo#231482
Users can now open an AI chat from the AI app even when several chats with the same AI agent are already open. This prevents an error that interrupted the workflow and makes the AI app behavior consistent with opening chats from the system tray.
Original PR description
Currently an error occurs when user tries to open an ai chat through the ai app while having a few ai chats open from the same ai agent. **Steps to replicate:** - Install `ai_app` and open AI app. -…
Currently an error occurs when user tries to open an ai chat through the ai app while having a few ai chats open from the same ai agent. **Steps to replicate:** - Install `ai_app` and open AI app. - Click on the AI icon in the system tray, open two chat windows. - Click on the `Ask AI` kanban card, the error will occur. **Error:** `ValueError: Expected singleton: discuss.channel(69, 70)` **Cause:** - Error occurs because there are already a few discuss channels active that are linked to the same ai agent, and the search query [1] returns multiple ids and ultimately multiple ids will be received at the the line [2] and cause the singleton error. **Solution:** - Ensure that only the first matching discuss channel is returned for a given AI agent when multiple channels exist. - Changed the method `action_ask_ai()` to always open a new ai chat, similar to when we click the ai icon in systray to maintain consistency. [1]: https://github.com/odoo/enterprise/blob/6b1c54d8a1c3b27e72a17d9984e632cc4afd8b64/ai/models/ai_agent.py#L686-L689 [2]: https://github.com/odoo/enterprise/blob/6b1c54d8a1c3b27e72a17d9984e632cc4afd8b64/ai/models/ai_agent.py#L432 **sentry-6849936794**
The point of sale iMin cashbox now uses the correct connection status before opening. This restores cash drawer opening for businesses using iMin hardware and prevents failed cashbox actions at checkout.
Original PR description
Explanation: openCashbox() is calling this.connected to check if iMin is connected. However the variable is changed to isConnected in the previous PR. Therefore it will always return null.
Creating invoices from multiple sales orders now keeps orders with different fiscal positions on separate draft invoices. This prevents incorrect tax or account calculations when orders require different fiscal treatment.
Original PR description
Problem: When a user selects multiple sale orders from the list view to create invoices, if the selected orders have different fiscal positions, they are all incorrectly merged into a single draft…
Problem: When a user selects multiple sale orders from the list view to create invoices, if the selected orders have different fiscal positions, they are all incorrectly merged into a single draft invoice. An invoice can only have one fiscal position. This merging causes unexpected behavior, as the accounts and taxes are computed based on the single (and potentially incorrect) fiscal position of the final invoice, rather than the respective fiscal positions of the originating SOs. Solution: This commit modifies the 'Create Invoices' action to group the selected sale orders by their `fiscal_position_id`. It will now create as many separate draft invoices as there are unique fiscal positions among the selected orders. task: 5188965 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#233119 Forward-Port-Of: odoo/odoo#232821
This fixes a problem where Odoo's automatic invoice sending could stop when a Spanish VeriFactu credit note was linked to an invoice without VeriFactu data. The process now skips affected records and reports them properly, so other invoices can still be sent automatically.
Original PR description
### Steps to reproduce: - Install l10n_es_edi_verifactu and switch too Spanish company - Create an invoice, add a nonzero product and Confirm - Select "Reverse" to create a credit note - Confirm the…
### Steps to reproduce: - Install l10n_es_edi_verifactu and switch too Spanish company - Create an invoice, add a nonzero product and Confirm - Select "Reverse" to create a credit note - Confirm the credit note - Select Send (or Send and Print), deselect everything except VeriFactu and email, then select Confirm - An error appears that takes the user to the failed record - Navigate to Accounting > Customers > Credit Notes - Select the credit note created and at least one other credit note, then select "Send" - Navigate to Settings > Technical > Scheduled Actions - Click into the "Send Invoices Automatically" record, then select "Run Manually" - Version 18.3: the scheduled action fails, no error message appears. The traceback can be seen in the logs - Version 18.0 and lower: The scheduled action fails, but an error message does appear ### Cause: When trying to generate the verifactu documents for a credit note whose invoice has no verifactu document, a `RedirectError` is raised. This means the scheduled action "Send invoices automatically" is cancelled if only one credit note as this issue: no invoices are sent. ### Solution: The usual way to handle user errors with the scheduled action is to append the key 'error' in the dictionnary `send_and_print_values`. This way a message is displayed when running the scheduled action mentioning the moves in error. So we check do the checks and remove the invalid moves before calling `_l10n_es_edi_verifactu_mark_for_next_batch()`. Like this we can change the key "error" in the dictionnary and stop the document generation there. We also extend `_hook_if_errors()` to raise a `RedirectWarning` if it's one of the errors related to Verifactu that we removed. opw-5091347 Forward-Port-Of: odoo/odoo#232763 Forward-Port-Of: odoo/odoo#230762
This fixes event registrations where Google's verification could expire if someone took more than two minutes to complete a long form. Attendees can now finish longer sign-up forms without being blocked by an expired verification check.
Original PR description
Description of the issue/feature this PR addresses: This PR aims to fix the timeout issue coming up for google recaptcha when the event registration form filing exceeds 2 mins(timeout value for google recaptcha tokens) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes inventory valuation for average-cost products when stock is scrapped using a packaging unit such as a pack of 6. Reports now subtract the correct quantity and value, helping businesses avoid overstated inventory values and inaccurate stock accounting.
Original PR description
**Steps to reproduce:** - Create a storable product. - Set the category as avco. - Set the cost to 10 - Set an on hand quantity of 10 - In the Sales tab, add 'pack of 6' to the packagings - Create a new scrap - Scrap 1 pack of 6 of this product - Open reporting/stock and search your product **Current behavior:** The value is 90 **Expected behavior:** It should be 40 **Cause of the issue:** get_valued_qty does not take into account the uom opw-5160608
Opening the invoicing dashboard no longer fails when Stripe expense card issuing is enabled but the company only has unsupported currencies active. The system now avoids creating or selecting Stripe issuing journals unless a valid supported currency is available, reducing setup disruptions for localized companies.
Original PR description
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. **Steps to…
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. **Steps to replicate:** * Install `account` without demo * Set Company currency to INR and deactivate USD in currencies. * Install `hr_expense_stripe` > Open Invoicing you will get the error. `ValueError: Expected singleton: res.currency()` **RootCause:** * When `hr_expense_stripe` is installed, the compute method [1] checks for supported currencies and defaults to USD if none are found. But since USD is often inactive by default in localized online databases, `stripe_currency_id` ends up empty . * Which causes [2] to pass an empty `stripe_currency_id` to [3], which expects at least one record, leading to the error. **Solution:** * Avoid creation of stripe issuance journal during installation when currency is not supported. * Add a constraint to check if stripe currency is valid for creating stripe issuance journal. * prevent creation and selection of journal for stripe issuing from settings. * [Reference Images](https://www.notion.so/Changes-in-Stripe-issuing-unsupported-vs-supported-2856722d865e803e8da1ece29cce7582?source=copy_link) for before and after functionality [1]: https://github.com/odoo/enterprise/blob/2ea15cc9c7c5f114b3786b256c64e269b3e3a313/hr_expense_stripe/models/res_company.py#L72 [2]: https://github.com/odoo/enterprise/blob/2ea15cc9c7c5f114b3786b256c64e269b3e3a313/hr_expense_stripe/models/account_journal.py#L52 [3]: https://github.com/odoo/odoo/blob/98bae80f57733162c67593539ef47dfd0c6d8797/odoo/addons/base/models/res_currency.py#L205 sentry-6916946380
Website builder sections using the "Repeat pattern" background option now show the image repeatedly as intended. This prevents visual layout issues on websites and email designs that rely on patterned backgrounds.
Original PR description
__Current behavior before commit:__ When setting the background image position to "Repeat pattern" in the website builder, the background image does not repeat as expected. This is due to conflicting…
__Current behavior before commit:__ When setting the background image position to "Repeat pattern" in the website builder, the background image does not repeat as expected. This is due to conflicting CSS rules where `background-repeat: no-repeat` from [`html_builder/static/src/scss/background.scss`][1] overrides the intended `background-repeat: repeat` from `html_editor.common.scss`. __Description of the fix:__ 1. Added `!important` to `background-repeat: repeat` to ensure the repeat pattern takes precedence over other styles 2. Removed duplicate and conflicting background styles from `mass_mailing/theme_default.scss` since these are already properly defined in `html_editor.common.scss` 3. Updated the test in `parallax_option.test.js` to verify `background-repeat: repeat` style is actually applied __Steps to reproduce:__ 1. Open website builder 2. Add a section with a background image 3. Change image position to "Repeat pattern" 4. Bug: background doesn't repeat [1]: https://github.com/odoo/odoo/blob/f0a34badefd432e9c2ab36acaf018d20d0e342fe/addons/html_builder/static/src/scss/background.scss#L25 task-5145343
This fixes cases where edit or write restrictions on related record fields were ignored, allowing users to modify data when the field configuration intended to block it. Businesses can rely more consistently on form settings to prevent unintended changes in related lists.
Original PR description
Before this commit, specifying the `edit` or `write` crud options on an x2many field didn't work. The `edit` action was overruled by the view mode (true iff the record datapoint is in edition), and the `write` action wasn't correctly honored in x2many. This commit ensures the `write` action is taken into account. In master, we'll rationalize this to merge `edit` and `write` in a single action. Task~5160367 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
Bank reconciliation rules using “Not Contains” on labels now match correctly even when some transaction text fields are empty. This helps accounting teams rely on automated reconciliation rules more consistently and reduces missed matches.
Original PR description
Currently bank reconciliation model match only the label type “Contains” The “not contain” type is not working Steps to reproduce: - Open Accounting Dashboard - Access Bank journal reconciliation models (3dots > Models) - Open a [Model] and set: - Label "Not Contains" "Test" - Add a Bank Statement with any label Issue: [Model] won't match Analysis: This occurs because in case the payment_ref or transaction_details contains a NULL value the ILIKE operations will evaluate to NULL, not TRUE or FALSE. Any other comparison involving NULL value will result in NULL and the whole condition will fail opw-5065006 [Task link](https://www.odoo.com/odoo/project/49/tasks/5065006) Forward-Port-Of: odoo/enterprise#97745
Repair service products that are published for sale are now correctly shown in the website shop. This prevents customers from missing eligible repair-related services when browsing or searching online.
Original PR description
Steps to reproduce: ------------------------- 1. Install repair and website_sale modules 2. Create a product that is the service type 3. Configure a product to create a repair order when the product…
Steps to reproduce: ------------------------- 1. Install repair and website_sale modules 2. Create a product that is the service type 3. Configure a product to create a repair order when the product is ordered 4. Publish the product from the Sales tab 5. Open the website without being signed in 6. Search for that product Observation: ------------------------- The product is not visible on the website shop. Issue: ------------------------- The method `_get_saleable_tracking_types(self)` is used to determine which product service tracking types are considered saleable on the website. However, this method was not defined for repair products, causing them to be excluded from the domain used to fetch saleable products. https://github.com/odoo/odoo/blob/b0203ae02d472bd7522bc21971f0e659766eaffe/addons/website_sale/models/website.py#L301-L308 Solution: ------------------------- Define the `_get_saleable_tracking_types(self)` method for repair products so they are properly included in website listings. opw-5102204 Forward-Port-Of: odoo/odoo#232154 Forward-Port-Of: odoo/odoo#231000
This fix prevents Odoo from creating many duplicate stock routes when a new warehouse is added after an existing global route has been renamed. It keeps warehouse setup cleaner and avoids confusion or extra maintenance for inventory teams.
Original PR description
In _find_or_create_global_route, use the asked 'route_name' instead of the potentially modified name of `data_route`. This ensures that if '_find_or_create_global_route' is called with the exact same values a new route will not be re-created. https://github.com/user-attachments/assets/815adf60-aa2d-4699-a79d-f9ad9607cbea ## How to reproduce (in runbot 17.0): - Enable "Multi-steps Routes" - Unarchive route "Replenish on Order (MTO)", change the name, set company to "My company (San Francisco)" - Go to "My Company (Chicago)" - Create new Warehouse => Check all the routes: ~100 MTO routes with the modified name have been created. OPW-5149842 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232829 Forward-Port-Of: odoo/odoo#232613
This fix prevents an error when users change the linked sales order from a delivery order. It ensures delivery records stay correctly connected to sales orders, avoiding interruptions during order fulfillment workflows.
Original PR description
Currently, an error occurs when user updates the sale order in the delivery picking. Steps to Reproduce: - Install the `sale_stock` and `sale_management` modules. - Create a `sale order` and…
Currently, an error occurs when user updates the sale order in the delivery picking. Steps to Reproduce: - Install the `sale_stock` and `sale_management` modules. - Create a `sale order` and `confirm` it. - Click the `Delivery button` on top of the order. - In the `Additional Info` tab of the sale order, select any order in `sale order` field and `save`. `psycopg2.ProgrammingError: can't adapt type 'sale.order'` `KeyError: <Command.LINK: 4>` This error occur after [this commit] where, after creating sale order, navigating to its delivery picking, and selecting the same or a different order, an invalid link caused the error[1]. This commit ensures that the sale order is linked correctly to the delivery picking. [this commit]: https://github.com/odoo/odoo/commit/2713876dbc70d3984e584a9037a2206dcda4e84a#diff-2b9de2e50ff5e1dc0362b825bac2b07623770fb3275b3257ef972f255f3ccb8bR172-R173 [1]- https://github.com/odoo/odoo/blob/d484516bcae1beb767d90d20e1ab294f1e9ae8a9/addons/sale_stock/models/stock.py#L173 sentry-6921046230 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users now receive a clear warning when trying to send batch invoices while the required scheduled process is disabled. This prevents silent failures and directs administrators to the right configuration so invoice sending can be restored quickly.
Original PR description
This commit raises a RedirectWarning to the cron configuration to inform the user that the batch invoice cron must be enabled. Batch invoices cannot be sent if cron is disabled. task-5122707 Current behavior before PR: If batch invoice send is called and cron is disabled, then it will silently fail and not send. Desired behavior after PR is merged: If batch invoice send is called and cron is disabled, then it will raise a RedirectWarning to the cron configuration. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229318
UPS shipping labels can now be generated even when the sender or shipper VAT number is not provided. This prevents production shipments from being blocked by a UPS error caused by sending blank tax ID values.
Original PR description
Only in production mode, if the sender or the shipper's VAT was not set, the UPS answer would be an error, preventing the label generation altogether. This is because we send an empty string if the VAT was not set, and UPS couldn't process it. Forward-Port-Of: odoo/enterprise#98227
Invoices sent together to Spain’s TicketBAI are now numbered in the correct posting order, from oldest to newest. This helps keep the legally required invoice chain consistent and avoids reversed numbering when users submit multiple invoices from a list.
Original PR description
Steps to reproduce: 1) Install l10n_es and l10n_es_edi_tbai. 2) Create a Spanish contact with a valid address and NIF. 3) Create several customer invoices and confirm (post) them. 4) From the list…
Steps to reproduce: 1) Install l10n_es and l10n_es_edi_tbai. 2) Create a Spanish contact with a valid address and NIF. 3) Create several customer invoices and confirm (post) them. 4) From the list view, select them and send to TicketBAI. 5) The TicketBAI “chain index” is inverted: the newest invoice gets the smallest index and the oldest gets the largest. The first invoice in the legal/chronological sequence is not index 1. Current behavior: - When sending multiple invoices at once, the processing loop uses the batch order as-is, which (from the list view) often arrives in reverse chronological order. The chain index is assigned incrementally based on that order, yielding an inverted chain (newest=1, oldest=N). Expected behavior: - The TicketBAI chain index must follow issuance/confirmation chronology: the oldest posted invoice in the batch is index 1, then 2, … up to the newest. Technical reason: - `_call_web_service_before_invoice_pdf_render` iterates `invoices_data.items()` without an explicit ordering by confirmation (posting) date. Depending on how the selection is built, items are processed newest-first, so the computed `chain_index` is reversed. Solution: - Sort the invoices before sending by posting date (`move.date`) ascending, with fallbacks to `invoice_date` and `create_date`, and a deterministic tiebreaker by `id`. Process sequentially after sorting and keep the per-invoice commit. opw-[5072667](https://www.odoo.com/odoo/my-tasks/5072667) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233105 Forward-Port-Of: odoo/odoo#229736
This fix prevents duplicate or incorrect work entry handling when employee attendance spans multiple days or uses different calendar types. It also stabilizes related tests and updates performance expectations so payroll and attendance calculations remain reliable.
Original PR description
- removed the logic for handling attendance spanning multiple days from `_create_work_entries` in `hr_work_entry_attendance` because it's already handled correctly in `_generate_work_entries_postprocess` - added `freeze_time` to `test_attendance_spanning_days` to always have summer timezone for the test. - adjusted some query counters to account for the extra search in `_attendance_intervals_batch` done by the method `_get_calendar_at` task-id: 5065160 Forward-Port-Of: odoo/enterprise#94715
This fixes an error that occurred when an HR responsible signed an employee offer involving requested extra time off with automatic allocation enabled. The change helps ensure the offer signing process completes smoothly when extra leave is part of the salary package workflow.
Original PR description
- When the employee requested extra time off, and the automatic allocation setting was turned on, signing the offer as the responsible HR caused an error. Task-5022631 Forward-Port-Of: odoo/enterprise#98195 Forward-Port-Of: odoo/enterprise#92663
This fixes a point-of-sale issue where clicking details within an order line could immediately close the numpad after opening it. Cashiers can now select order line details, such as eWallet balance information, without the numpad flickering or becoming unusable.
Original PR description
Steps to reproduce: =================== - Click on an orderline - Then click on a detail inside it (e.g., eWallet Balance line) - The numpad first opens and then closes right away Issue: ====== - Clicking on a detail inside the orderline makes the numpad open and close at the same time - This makes it impossible to use the numpad properly Cause: ====== - The click from the child element also reaches the main orderline click - Because of this, the numpad gets two clicks (open and close) Fix: ==== - Added `stopPropagation` in the click handler to block event bubbling - Now the numpad only reacts once and stays open as expected Task: 5000327 Forward-Port-Of: odoo/odoo#233201 Forward-Port-Of: odoo/odoo#227675
Sale orders that use only fixed taxes can now be read reliably through XML-RPC without causing a serialization error. This prevents integrations and external systems from failing when retrieving affected sales or accounting data.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a fixed tax; 2. create a sale order using only the fixed tax; 3. read the sale order via XML-RPC. Issue ----- TypeError: cannot marshal None unless allow_none is enabled Cause ----- If only a fixed tax is used, the `_get_tax_totals_summary` method returns a dict where the `display_base_amount_currency` and `display_base_amount` values are `None`, leading to an error serializing the result. Solution -------- As the result gets serialized by `OdooMarshaller(allow_none=False)`[^1], we should use `False` instead of `None`. [^1]: https://github.com/odoo/odoo/blob/b887bf2/odoo/addons/base/controllers/rpc.py#L114 opw-5173477 Forward-Port-Of: odoo/odoo#232955 Forward-Port-Of: odoo/odoo#232517
This fixes an upgrade issue where bank account setup could fail when no bank account code prefix was configured. The system now treats the missing prefix safely, helping affected accounting migrations complete without errors.
Original PR description
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False. ```traceback…
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False.
```traceback
module l10n_co: Running migration [$1.0] end-migrate_update_taxes
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 523, in load_modules
migrations.migrate_module(package, 'end')
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 222, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 259, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/odoo/18.0/addons/l10n_co/migrations/1.0/end-migrate_update_taxes.py", line 8, in migrate
env['account.chart.template'].try_loading('co', company)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 160, in try_loading
return self._load(template_code, company, install_demo, force_create)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 228, in _load
self._post_load_data(template_code, company, template_data)
File "/home/odoo/src/enterprise/18.0/account_reports/models/chart_template.py", line 10, in _post_load_data
super()._post_load_data(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 681, in _post_load_data
self._setup_utility_bank_accounts(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 845, in _setup_utility_bank_accounts
accounts = self.env['account.account']._load_records([
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5526, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5430, in _load_records_create
records = self.create(vals_list)
File "<decorator-gen-208>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 498, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/addons/account/models/account_account.py", line 997, in create
start_code = prefix.ljust(digits - 1, '0') + '1' if len(prefix) < digits else prefix
TypeError: object of type 'bool' has no len()
```
Databases affected by this traceback error:
https://upgrade.odoo.com/odoo/request/3191023/tbg/2150
task-5167397
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#232169This fix ensures employee work entries are generated correctly when staff have different working schedule types, flexible schedules, or schedule changes over time. It also prevents errors and incorrect time zones that could affect payroll-related records, including avoiding zero-duration entries for multi-day attendances.
Original PR description
- fixed work entries generation for employees with different working schedules types - fixed a traceback when the method `_attendance_intervals_batch` is called without a calendar (because the employee is fully flexible) or with more than 1 calendar - made work entries generation check for employee timezone incase the employee is fully flexible and doesn't have a calendar - added method _get_calendar_at to get the calendar of the resource at a given date - added `test_work_entry_different_calendars` for work entries generation for employees with contracts with different calendar types - fixed a timezone bug in `_generate_work_entries_postprocess` where `date_start_utc` and `date_start_utc` had `tzinfo = None` and not `utc` which resulted in having wrong timzones afterwards. - fixed a bug where a work entry with zero duration is created between days for attendances that span multiple days task-id: 5065160 Forward-Port-Of: odoo/odoo#226619
This fix prevents the messaging connection from wrongly treating a user as changed when some pages omit database details. Users keep their own presence updates reliably, so status changes across multiple browser windows are reflected correctly.
Original PR description
The websocket worker holds a single WebSocket connection per browser. Clients pass the current user ID and DB name, which the worker uses to detect login/logout. Some pages omit the DB name, causing…
The websocket worker holds a single WebSocket connection per browser. Clients pass the current user ID and DB name, which the worker uses to detect login/logout. Some pages omit the DB name, causing the worker to incorrectly mark the user as changed. This clears previous channels, which may never be added back. This is particularly noticeable with presence channels: the user's own channel can be lost, preventing them from receiving their own presence updates (e.g. when another browser closes, the user cannot see they are disconnected and cannot correct the value). The user's own presence channel should be added server-side, so the first subscription immediately returns the user presence and the DB should not be taken into account if ommited. task-5096212 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#233277 Forward-Port-Of: odoo/odoo#232984
This fix resolves an error that could stop customers from completing payments through Mercado Pago. It removes a faulty internal call so the payment form can proceed as expected.
Original PR description
'_super' is removed, since the binding of 'this' is no longer needed and since 'super' is not a function it caused an error and prevented the payment.
Administrators without Employees access can now open user records without hitting an employee permissions error. The HR calendar section is only shown to users with HR rights, preventing irrelevant employee data from blocking access.
Original PR description
Steps to reproduce : switch Marc Demo as "Administrator" + ensure we has no "Employees" rights, connect as him and try to open his user form view (Settings / Users / Users) it crashed with: "You do…
Steps to reproduce : switch Marc Demo as "Administrator" + ensure we has no "Employees" rights, connect as him and try to open his user form view (Settings / Users / Users) it crashed with: "You do not have enough rights to access the field "version_id" on Employee (hr.employee). Please contact your system administrator." Reason : a hidden Many2one field linking to hr.employee model, thus when the view is loaded this field causes an access to the model employee , given the current user doesn't have the rights , it causes an error. Fix : made the calendar page invisible for people with no hr rights , because there is a same view that can be accessed through the preference menu that contains the user's own info , otherwise , even with admin rights , if he doesn't have employee rights he is not concerned with the content of the calendar page of his or other user's form view. so it should be hidden from him. Fix : made the calendar page visible only for target users , in our case , users part of the following group : "hr.group_hr_user" task-5173101
11 changes
Enhancements to existing features
The Italian localization no longer allows obsolete Natura tax exemption reasons that are rejected by the Italian Tax Agency. This helps businesses issue electronic invoices with valid tax codes and reduces the risk of submission errors.
Original PR description
There are old Natura (l10n_it_tax_exemption_reason) that are deprecated in favour of more detailed ones. We already have the detailed ones, but we allow the old values, but the Tax Agency considers them invalid already. ref: https://fex-app.com/FatturaElettronica/FatturaElettronicaBody/DatiBeniServizi/DatiRiepilogo/Natura Forward-Port-Of: odoo/odoo#226939
Resolved issues and error corrections
This fixes an issue where accrued leave days expiring after carryover could be undercounted when an allocation started before the carryover date. Employees and HR teams should now see the correct number of expiring leave days, improving accuracy in time off balances.
Original PR description
To reproduce: ============= - Create an accrual plan: - Carryover date: allocation - One level: - Accrues 2 days. - Accrual date: monthly on 1st of each month - Starts immediately on allocation start…
To reproduce:
=============
- Create an accrual plan:
- Carryover date: allocation
- One level:
- Accrues 2 days.
- Accrual date: monthly on 1st of each month - Starts immediately on allocation start date - Carryover policy: all days carry over - Carried over days validity: 3 months.
- Create an allocation that uses the above accrual plan on 23/09/2025:
- Starts on 01/07/2024
we should have 30 days in total with 24 expiring on 01/10/2025 but we only have 22 expiring on 01/10/2025.
Problem:
========
we loop on each month in the allocation period to compute the accrued days when we reach the carryover date (01/07/2025) we set the expiring_carryover_days to the number of days accrued until that date which is 22 as we didn't yet add the days for June 2025, it's done after.
Solution:
=========
add additional accrued days when setting expiring_carryover_days on carryover date.
opw-4963163
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fixes an issue where exporting records could fail when property fields relied on a computed company-related definition. Users can now export affected data normally, reducing disruption for teams using customized property fields.
Original PR description
**Description of the issue/feature this PR addresses:** Setup a model with a computed definition record field, like so: ```py properties_company_id = fields.Many2one(…
**Description of the issue/feature this PR addresses:**
Setup a model with a computed definition record field, like so:
```py
properties_company_id = fields.Many2one(
compute="_compute_properties_company_id",
comodel_name="res.company",
)
@api.depends("company_id")
@api.depends_context("company")
def _compute_properties_company_id(self):
for item in self:
item.properties_company_id = item.company_id or self.env.company
```
Use this in a `Properties` definition:
```py
properties = fields.Properties(
definition="properties_company_id.properties_definition",
)
```
Then simply try to export the model.
**Current behavior before PR:**
```python-traceback
Traceback (most recent call last):
File "/odoo/src/odoo/odoo/http.py", line 2166, in _transactioning
return service_model.retrying(func, env=self.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/odoo/service/model.py", line 156, in retrying
result = func()
^^^^^^
File "/odoo/src/odoo/odoo/http.py", line 2133, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/odoo/http.py", line 2381, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/addons/web/controllers/export.py", line 400, in get_fields
exportable_fields.update(self._get_property_fields(fields, model, domain=domain))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/addons/web/controllers/export.py", line 321, in _get_property_fields
field_to_get = Model._field_to_sql(Model._table, definition_record, self_subquery)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/odoo/models.py", line 2973, in _field_to_sql
return model._field_to_sql(alias, field.name, query)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/odoo/src/odoo/odoo/models.py", line 2976, in _field_to_sql
raise ValueError(f"Cannot convert {field} to SQL because it is not stored")
```
**Desired behavior after PR is merged:**
Should not fail.
With this commit, the code fallbacks to export all properties defined, even those that are not used among the exported records.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix ensures Safari users can apply or dismiss links in the HTML editor without the popover closing too early. It also restores reliable use of the link type selector, helping users edit email templates and other rich text content without failed or incomplete link changes.
Original PR description
## Issue: On Safari, the Apply and Dismiss buttons of the LinkPopover did not trigger their actions In some cases, it seemed to work only because a temporary link was not properly cleared The Link…
## Issue: On Safari, the Apply and Dismiss buttons of the LinkPopover did not trigger their actions In some cases, it seemed to work only because a temporary link was not properly cleared The Link Type Selection was also broken by the same bug ## Cause: Safari triggers a `pointerdown` event through the `LinkPopover`, which changes the `selection` and calls the `handleSelectionChange()` method https://github.com/odoo/odoo/blob/e43135e94bf22bc2f7a115c37e8a082f96871ed0/addons/html_editor/static/src/main/link/link_plugin.js#L672-L678 At that point, `documentSelection` is `null`, causing the overlay to close before the `onClickApply()` on the Apply button It's the same issue with the Dismiss button and the Link Type Selection ## Steps to reproduce: - Install mail to get access to an html_editor - Enable debug mode - Go in Email Templates and open one of them - Select a text and open link tools - Add Odoo.com and click on Apply - The link may seems to be created (if it's the case, there is no preview) - You can confirm that with the link type selector that closed the popover before the fix opw-5115887
Module updates now avoid reactivating or disabling existing website assets based only on their original configuration. This prevents older website snippets still used on live pages from losing required assets after an update, helping keep existing website content displayed correctly.
Original PR description
Before this commit when a module was updated all ir.asset records were reset to their defined `active` state, if defined. This causes assets related to old snippet versions to be made inactive even…
Before this commit when a module was updated all ir.asset records were
reset to their defined `active` state, if defined.
This causes assets related to old snippet versions to be made inactive
even if those old snippet versions are used inside existing pages.
It used to work when the activation of assets was made through view
inheritance because when views are defined through a `<template>` tag,
the `active` attribute is in fact ignored during updates since [1],
except for new records since [2].
This commit introduces an `<asset>` tag in the XML import format.
It is an alias of `<record ... model="ir.asset">` with the additional
feature that it avoids taking the `active` field into account during
updates for existing `ir_asset` records, just like `<template>` if the
`active` field is mentioned as attribute of the tag.
We then rely on the `website_disable_unused_snippets_assets` cron to
properly disable any unused asset at a later stage (note that the bug
being fixed here was mitigated by the fact that cron also re-enabled
assets which were disabled by mistake... but that might happen only a
few days later).
Another approach was to overload `_load_records_write` in `base`'s
`ir_asset.py` to avoid taking the `active` field into account when
updating records:
```py
def _load_records_write(self, values):
values.pop('active', None)
super()._load_records_write(values)
```
But this is not as stable because it changes the way `ir.asset` records
are imported when the `<record>` tag is used. In the end we chose to be
consistent and do exactly the same as `<template>`, as this also allows
more and should be entirely stable.
[1]: https://github.com/odoo/odoo/commit/2d296cb77922d33be2dc45b900191fac34bda429#diff-175c28787c272a219b9275f79262a48af9aa029e718f45077fd609737559e84eR803-R804
[2]: https://github.com/odoo/odoo/commit/f1c70d4cc943ac4eb81a85a9dc005de34cd2060a#diff-175c28787c272a219b9275f79262a48af9aa029e718f45077fd609737559e84eR801-R804
task-2963840
(Follow-up of https://github.com/odoo/upgrade/pull/3829)
Forward-Port-Of: odoo/odoo#104836This update prevents duplicate partner identification values from being sent in Colombian and Peruvian electronic invoice files. It helps avoid validation errors from tax authority rule sets that only accept one party identification per partner.
Original PR description
odoo/odoo#206655 added the partner ref in the party identification nodes, but most rule sets don't accept multiple ids for a single partner party identification. Commit 4e22e6b already fixed the issue for malaysian edi. so instead of calling super and extending, we do full overriding with no delegation for `_get_partner_party_identification_vals_list`. community pr: https://github.com/odoo/odoo/pull/213530 no-task
UPS label generation could fail in production when sender or shipper VAT details were left blank. This fix avoids sending empty tax ID values to UPS, helping businesses create shipping labels successfully even when VAT information is not available.
Original PR description
Only in production mode, if the sender or the shipper's VAT was not set, the UPS answer would be an error, preventing the label generation altogether. This is because we send an empty string if the VAT was not set, and UPS couldn't process it. opw-5214709
Improves inventory performance when warehouses have many transfers with quality checks. The change reduces memory usage significantly, helping prevent worker crashes when users open the To Receive view.
Original PR description
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive"…
The fields `quality_check_todo` and `quality_check_fail` are calculated for stock.picking records by iterating all checks of a stock.picking. This causes a problem when clicking the "To Receive" button for a warehouse in the inventory app, in case there are many transfers each with many quality checks. The function will default to loading all data associated with quality checks in memory through field prefetching. However, since quality checks have too much data (particularly because of the HTML fields) associated with them, the cache can quickly bloat causing an OOM error and crashing the worker. This PR disables the prefetcher for quality checks before iterating them, preventing this issue from happening since we only need very light fields in the loop. For a specific customer (opw-5025162), this was the case. Benchmarks: | No. stock.picking | avg no. quality checks | peak memory before | peak memory after | | ----------------- | ---------------------- | ------------------ | ----------------- | | 25 | 20 | 2771 mb | 235 mb | opw-5025162
This update restores the Swedish POS rule that limits receipt reprints to one time, helping businesses stay compliant and avoid duplicate receipt handling issues. It also improves blackbox error handling so disconnected devices or unexpected errors no longer leave the interface stuck loading.
Original PR description
Before this commit, the receipt reprint check logic (which only allows a receipt to be reprinted once) was not working. There were two issues preventing it from working: - The name of the function had changed but not been updated in this module, so the override was not applied. - The ID being used to check the order was incorrect. A few smaller issues were also fixed: - A logging issue in the IoT driver, which prevented the error severity from being printed. - An infinite loading UI if the blackbox was disconnected. - The blackbox error handler swallowing up some errors due to only expecting one specific format. Forward-Port-Of: odoo/enterprise#98076
The report editor now handles conditional table headers more reliably when adding columns. This prevents cases where inserting a column in documents like Delivery Slips only updated the header row instead of the full table.
Original PR description
The TableSizeComputer.compute() method can return cells with incorrect cell indexes. This can result in the _addColumn function only adding a column to some rows in the report editor.…
The TableSizeComputer.compute() method can return cells with incorrect cell indexes. This can result in the _addColumn function only adding a column to some rows in the report editor. TableSizeComputer.compute() does not handle cases where a conditional is used inside of a th element but the corresponding td element does not have a conditional. Steps to reproduce ----- 1. Open the Delivery Slip in the report editor. 2. Click the header to show the dropdown and select elif: o.move_line_ids and o.state=='done'. 3. Hover over the last th element to select the column button. 4. Click Insert right and see that only the header row has an additional column. Cause ----- TableSizeComputer.compute() calculates how many possible cells can be in a row which can be more than the total number of columns you have if you have th or td elements with a conditional inside of them. In the Delivery Slip report, a th element is present when using serial numbers and a different th element is present when not using serial numbers. The corresponding t-body has two different tr elements for these conditions. The compute method will have one less cell in these rows because the corresponding conditional is handled outside of the row. Solution ----- Only count mutually exclusive th or td elements once. This prevents the cellIndex from being larger than the total possible columns. opw-ticket 5173345
This update prevents users from disabling required Peppol e-invoicing services, reducing the risk of compliance problems. It also fixes missing invoice print options in the actions menu and improves the consistency of e-invoice format labels.
Original PR description
#### [FIX] account_peppol: disallow disabling services Currently it is possible to disallow any services in the configuration. This can lead to complicance issues; i.e. if someone disables "BIS…
#### [FIX] account_peppol: disallow disabling services Currently it is possible to disallow any services in the configuration. This can lead to complicance issues; i.e. if someone disables "BIS Billing 3.0". 1. Ensure Peppol is activated (test mode or production; not demo) 2. Settings -> Accounting -> PEPPOL Electronic Invoicing -> Configure Peppol Services 3. Any service can be disabled. This commit hides the button to open the service wizard. (Also in the wizard it is now not possible to disable services anymore.) #### [FIX] account: generation of print-related entries in cog menu Before this commit: The dynamic generation of the print related entries in the cog menu does not work correctly. Problem / Solutions: There is a check in the javascript that does not work as intended. Thus the entries are not added to the cog menu in all cases. The check was intended to only block it for "new" records (not saved yet); to avoid issues in case the move has no id yet. After this commit we just check the id directly. #### [FIX] account_edi_ubl_cii: missing parenthesis in invoice_edi_format Follow-up to commit 860c0974f9b541be63f4079ef52366f91c1994ce . There we improved the eInvoice format labels for clarity. But 2 label were formatted differently than the others. This commit fixes that. #### References task-4737164
5 changes
Enhancements to existing features
The Italian localization no longer allows outdated tax exemption reason codes that the Italian Tax Agency now rejects. This helps businesses avoid invalid electronic invoices by using the newer, more detailed codes already available in Odoo.
Original PR description
There are old Natura (l10n_it_tax_exemption_reason) that are deprecated in favour of more detailed ones. We already have the detailed ones, but we allow the old values, but the Tax Agency considers them invalid already. ref: https://fex-app.com/FatturaElettronica/FatturaElettronicaBody/DatiBeniServizi/DatiRiepilogo/Natura
Stock movement validation is faster when putaway rules are involved because the system now reuses the same location calculation across related move lines. This reduces repeated work and can significantly cut processing time for large warehouse operations.
Original PR description
Previously when validating a movement with a location that is used in a rule, move_dest_ids was set which led to it going to check the putaway strategy. The bottleneck was the computation of the computed field child_internal_location_ids which is the same across all smls. This PR utilizes the fact that the smls in the same stock_move would have the same destination location and by proxy the same child_internal_location_ids Speed up: 1000 stock move lines: Before: 2 mins After: 1 mins --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo VoIP now tries to close unused phone registrations when a browser tab is closed and shortens how long abandoned registrations remain active. This helps prevent users from hitting provider limits when they have multiple Odoo tabs open or close tabs unexpectedly.
Original PR description
Some providers like OnSIP allow for a limited number of registrations per user. This is a problem in Odoo because each tab opened creates a new registration for one hour. This commit mitigates the problems in two ways: - Sends an "unregister" request onbeforeunload to try to invalidate the registration upon closing the tab. - Reduces the TTL of registrations so that they get invalidated quicker in case the unregistration failed.
Resolved issues and error corrections
Updating the quantity to produce for subcontracted manufacturing orders no longer creates extra component lines without lot or serial numbers when stock is already reserved. This reduces manual corrections and helps users validate receipts without avoidable lot/serial errors.
Original PR description
,*=mrp_subcontracting_purchase Issue Before This Commit: ======================= When a user updates `qty_producing` in a subcontracting MO, it creates new move lines with empty lots or serials, even…
,*=mrp_subcontracting_purchase Issue Before This Commit: ======================= When a user updates `qty_producing` in a subcontracting MO, it creates new move lines with empty lots or serials, even though the required quantity is already available in existing reserved move lines. This requires the user to manually reassign lots/serials; otherwise, validating the picking raises a UserError of `missing Lot/Serial numbers`. Steps to Reproduce: ======================= - Install the `mrp_subcontracting_purchase` module. - Create product1 with Vendor1. Create product2 with lot tracking and set it `Resupply Subcontractor on order` in Inventory. - Create a BOM for product1, with product2 as a component (quantity 10) and subcontractor Vendor1. - Create and confirm a purchase order for product1 (quantity 10) with Vendor1. - Go to Resupply → Supply Product2, deliver 100 units of Product2 to Vendor1 using lot-01, then validate the picking. - Go to the source PO → Receipt → Record Component. Observe that the move line is created with 100 units from lot-01 - Set qty_producing to 5 → the current component line updates to 50 quantity. - Increase qty_producing to 10 → a new line is created with empty lot and quantity 50, even though the existing line already has 100 of the same lot. Cause of the issue: ======================= When `qty_producing` is updated in the subcontracting MO wizard, the `_set_quantity_done_prepare_vals` method recalculates quantities based on the already modified move line quantity instead of referencing its original `reserved quantity`.This causes incorrect comparisons on subsequent updates, leading to the creation of new move lines with empty lots even when sufficient quantity already exists in the existing move line. With This Commit: ======================= `_set_quantity_done_prepare_vals` method now uses `ml._origin.quantity or ml.quantity`. ` _origin.quantity` ensures the reserved quantity of existing move lines is counted, while `ml.quantity` handles newly created lines without an origin. This prevents unnecessary move lines with empty lots when sufficient quantity already exists in existing reserved lines, eliminating manual reassignment and avoiding UserError on picking validation.
Belgian payroll now correctly stops paying public holidays that fall during long-term sick leave after the 30-day threshold. This prevents overpayment and helps payroll calculations follow Belgian employment rules more accurately.
Original PR description
Bug: In Belgium, after 30 calendar days of sick leave, all public holidays during the sick leaves are no longer paid. But here they were still being paid. Cause: The method that was checking what to do about public holidays was never seeing public holidays since they were already changed to their corresponding work entries at the work entry generation. Fix: Add the public holidays in the context and change the condition for checking if the current leave is actually from a public holiday or not. Task: 3864585