Daily updates from Odoo
Thursday, March 27, 2025
29 changes · master
New functionality added to Odoo
Introduces a new AI app that lets users chat with an AI agent to request actions in Odoo, such as planning meetings. The feature adds configurable agent topics and actions, document processing for better responses, and background processing to prepare AI knowledge from business documents.
Original PR description
## Purpose We want to allow the user to ask an AI operator (agent) to perform operations on their database (i.e. planning a meeting) by chatting with it. task id: 4526285
Enhancements to existing features
The checkout cart layout has been updated to work better on mobile devices, reducing overlap and making product details easier to read. Related rental, subscription, appointment, and stock sale flows were aligned so customers get a more consistent shopping experience across different product types.
Original PR description
Follows the changes made in community to achieve the following goals: - Better Mobile Layout: Fix overlapping elements and ensure all product information is visible. - Consistent Design: Align layouts across cart_lines and suggested products for a uniform look. - Enhanced Usability: Streamline interactions and navigation for a smoother user experience. task-4387239 Community PR: https://github.com/odoo/odoo/pull/190720 Upgrade PR: https://github.com/odoo/upgrade/pull/7446
When an IoT box is removed from the database, it is now automatically told to clear its server pairing. This prevents devices from remaining stuck as already paired and lets a new pairing code appear without manual intervention.
Original PR description
Community PR: https://github.com/odoo/odoo/pull/203728 This commit adds an `ondelete` handler to the IoT box model, which sends a `server_clear` websocket message to the IoT box. This prevents the IoT box from being stuck in the paired state, and a new pairing code will instead automatically appear. task-4648508
The subscription product catalog now focuses on recurring products and shows prices that match the selected billing plan, such as monthly or yearly. This helps sales users choose the right subscription products with fewer pricing surprises before adding them to an order.
Original PR description
Before this commit: - Clicking on the product catalog from a subscription showed all products, both recurring and non- recurring. - The catalog did not display prices based on the recurring plan monthly/yearly selected in the sales order, leading to confusion about price differences before and after adding products. After this commit: - A filter for recurring products is added to the catalog. - Prices in the catalog now reflect the recurring plan (e.g., monthly or yearly) selected in the sales order. task-4395226
Documents now use a custom drag-and-drop experience instead of the browser’s older built-in behavior. Users get clearer visual feedback when moving documents, creating shortcuts, or attempting actions in restricted folders, making document organization easier and less confusing.
Original PR description
Commit 1 : [REM] documents: remove all old dnd feature Remove old dnd api related code Commit 2 : [IMP] documents: use makeDraggableHook instead of DnD API This commit implements a new draggable hook for documents by using the `makeDraggableHook` utility instead of using the HTML DnD API. The HTML DnD API had some limitations especially regarding the created element which follows the mouse during the DnD. It is actually a snapshot from the dragged element thus not editable... So in addition of centralizing all the drag and drop logic in one file, we can have a visual help when pressing a modifier key (control) when dragging some documents to inform the user that he will create shortcuts instead of moving the selected documents. The user will also have a visual help when he tries to DnD documents in restricted folders or if he doesn't have the rights to move. Task-4306387
Businesses can now set up a virtual IoT box to send print jobs directly to email-based printers. This simplifies printer setup and reduces reliance on dedicated IoT hardware for email printing workflows.
Original PR description
In this commit: ================= - Added virtual IoT box to enable sending print attachments to email printers directly. - Allows printing to email printers without routing through a physical IoT device. - The virtual IoT box acts as a direct channel for handling email-based printing simplifying the setup and reducing dependency on hardware. Task-4626102
Short time formatting now follows Odoo’s own language settings instead of relying on external defaults. This keeps displayed times consistent across apps and improves handling of AM/PM translations in some languages.
Original PR description
Description of the issue/feature this PR addresses: - Usage of short_time_format effectively which is already defined in base. - Test cases updated accordingly. Current behavior before PR: - While using format_time method, time_format='short' used babel's time format. - These time formats do not match with Odoo base (res.lang.csv) ex: locale='en_US' in babel is 12 hr format while res.lang.csv defines it as '%H:%M:%S'. Desired behavior after PR is merged: - time_format='short' while now access the short_time_format defined in base ( res.lang.csv). - 'short' will allow to only remove seconds from the time format, and not changing the whole format itself. - AM/PM language translations in few languages (ex. zh_CN) are better handled in base, unlike babel.
Resolved issues and error corrections
This fix prevents marketing campaign setup from failing in a specific case after a related default value was removed. It helps ensure marketing automation actions continue to work reliably for users creating or managing campaigns.
Original PR description
In [1], the first commit removes the server actions state field default value which made the marketing.campaign model to fail in a certain case. This commit fixes the issue. Task id: opw-4648932 [1]: https://github.com/odoo/odoo/pull/202347
Filtering records by date and time now handles non-UTC time zones more consistently. This reduces errors for users working with appointments, attendance, planning, projects, timesheets, and sales planning across different regions.
Original PR description
When filtering, always use naive datetimes to avoid errors when the datetime is not in the UTC timezone. odoo/odoo#203047
Code cleanup and technical improvements
Odoo IoT now recognizes touchscreens as a dedicated type of display instead of requiring separate display and keyboard registrations. This simplifies device setup for self-ordering and other touchscreen-based workflows, reducing configuration confusion.
Original PR description
Added a new subtype 'touchscreen' for displays, to avoid registering a touchscreen using a display and a keyboard. Community PR: [https://github.com/odoo/odoo/pull/201128](https://github.com/odoo/odoo/pull/201128) Task: 4627191
The Frontdesk and Social Twitter areas now use a newer, more flexible way to show autocomplete choices. This is an internal cleanup that should preserve current behavior while making future interface changes easier.
Original PR description
\* frontdesk, social_twitter This commit removes the props `optionTemplate` from `AutoComplete` and replaces all occurence by `optionSlot`. Slots give more power than templates. If we want to use a template, we can still `t-call` it in the slot. task-4660366
Miscellaneous changes
This error occurs when we click on `try a sample receipt` in the Expense module. Steps to reproduce: --- - Install `hr_expense_extract` module(without demo) - Expenses > `try a sample receipt` Traceback: --- ``AttributeError: 'hr.expense' object has no attribute '_default_journal_id'`` At [1], we are encountering this error because the `_default_journal_id` method is defined in `hr.expense.post.wizard`, but we are attempting to access it from `hr.expense`. https://github.com/odo
Original PR description
This error occurs when we click on `try a sample receipt` in the Expense module. Steps to reproduce: --- - Install `hr_expense_extract` module(without demo) - Expenses > `try a sample receipt` Traceback: --- ``AttributeError: 'hr.expense' object has no attribute '_default_journal_id'`` At [1], we are encountering this error because the `_default_journal_id` method is defined in `hr.expense.post.wizard`, but we are attempting to access it from `hr.expense`. https://github.com/odoo/enterprise/blob/e10f9aa43ebc4368050c4cb904e81253fc324bdc/hr_expense_extract/wizard/expense_sample_receipt.py#L51 sentry-6362357345 Forward-Port-Of: odoo/enterprise#80858
Accessing the tax report from a branch company raised a user error due to attempting to fetch tax group XML IDs using the company’s CID. While this could be resolved by using `self.env["account.chart.template"].ref`, the report isn’t intended to be shown for branch companies. Instead, a constraint was added to prevent access in such cases. opw-4569580 Forward-Port-Of: odoo/enterprise#82153 Forward-Port-Of: odoo/enterprise#82101
Original PR description
Accessing the tax report from a branch company raised a user error due to attempting to fetch tax group XML IDs using the company’s CID. While this could be resolved by using `self.env["account.chart.template"].ref`, the report isn’t intended to be shown for branch companies. Instead, a constraint was added to prevent access in such cases. opw-4569580 Forward-Port-Of: odoo/enterprise#82153 Forward-Port-Of: odoo/enterprise#82101
Since https://github.com/odoo/odoo/pull/185240 customers are given as default or suggested recipients for communications. Both chatter and templates proposes them by default. Followers should now be mostly be internal users that want to receive news from a record while customers should be actively displayed and chosen. In this task we remove some of auto subscription done in code. This is done on models where it has few impact. A master PR will be done for models more tightly coupled wi
Original PR description
Since https://github.com/odoo/odoo/pull/185240 customers are given as default or suggested recipients for communications. Both chatter and templates proposes them by default. Followers should now be mostly be internal users that want to receive news from a record while customers should be actively displayed and chosen. In this task we remove some of auto subscription done in code. This is done on models where it has few impact. A master PR will be done for models more tightly coupled with followers, like SO, invoices, timesheets, ... See sub commits for more details. Task-4655022 Forward-Port-Of: odoo/enterprise#82196
During this commit: https://github.com/odoo/enterprise/commit/eae026d97399e0cf77c4d55fa1975968a27a3d2d We adapted the report to IMB. But by doing so there was some mistake in the report. opw-4625920 Forward-Port-Of: odoo/enterprise#81313
Original PR description
During this commit: https://github.com/odoo/enterprise/commit/eae026d97399e0cf77c4d55fa1975968a27a3d2d We adapted the report to IMB. But by doing so there was some mistake in the report. opw-4625920 Forward-Port-Of: odoo/enterprise#81313
Before this commit, it was possible to pay payment links linked to renewed orders. It would cause issues as the renewed order would be reopened once the transaction was set to done. Two subscription in progress would live side by side. This commit ensure that such links can't be created and existing links can't be used. taskid: 4607315 Forward-Port-Of: odoo/enterprise#82223 Forward-Port-Of: odoo/enterprise#80388
Original PR description
Before this commit, it was possible to pay payment links linked to renewed orders. It would cause issues as the renewed order would be reopened once the transaction was set to done. Two subscription in progress would live side by side. This commit ensure that such links can't be created and existing links can't be used. taskid: 4607315 Forward-Port-Of: odoo/enterprise#82223 Forward-Port-Of: odoo/enterprise#80388
In the bank reconciliation widget, when the transaction_details of bank statement lines get formatted by calling json.loads(), an error will show if some strings contain control characters (`\n`, `\t`, `\r`, `\0`). Adding the parameter `strict=False` to the call to json.loads would allow such characters to be kept by the formatting. In the view, they will not be used (any of those 4 chars will simply be considered a whitespace). One could add `style="white-space: pre-line"` as an attribut
Original PR description
In the bank reconciliation widget, when the transaction_details of bank statement lines get formatted by calling json.loads(), an error will show if some strings contain control characters (`\n`, `\t`, `\r`, `\0`). Adding the parameter `strict=False` to the call to json.loads would allow such characters to be kept by the formatting. In the view, they will not be used (any of those 4 chars will simply be considered a whitespace). One could add `style="white-space: pre-line"` as an attribute to the span tag of those element, but this is not necessary. This PR simply aims to patch the already existing data in databases. opw-4480250 Forward-Port-Of: odoo/enterprise#78684
Steps to reproduce the bug: - Install l10n_es_real_estate module - Create a customer invoice on the accounting app - Invoice's AEAT data should be real estate type for mod347 doc - Generate the BOE of tax report document of mod 347 Traceback is thrown while generating the boe of the mod347 document, the traceback is for an issue related to the param of the operation key and that was because the function _call_on_partner_sublines is run for each real estate invoice and it has a callback
Original PR description
Steps to reproduce the bug: - Install l10n_es_real_estate module - Create a customer invoice on the accounting app - Invoice's AEAT data should be real estate type for mod347 doc - Generate the BOE of tax report document of mod 347 Traceback is thrown while generating the boe of the mod347 document, the traceback is for an issue related to the param of the operation key and that was because the function _call_on_partner_sublines is run for each real estate invoice and it has a callback to be executed on each of them. The callback function is _write_type2_partner_record which should have the report option as param, but it wasn't sent that made a traceback for the params. After fixing that, another traceback was thrown because the xmlid of the real estate invoices of both sold and bought are not in the invoice types map of _write_type2_partner_record function. opw-4589314 Forward-Port-Of: odoo/enterprise#82008 Forward-Port-Of: odoo/enterprise#81033
Inverse the domain on `subscription_state` from: `not in (selection_values)` -> `in (complement(selection_values))` Using the `in` operator gives Postgres the possibility to use an index on `subscription_state`, which cannot be done with a `not in` domain operator for `Selection` fields. Forward-Port-Of: odoo/enterprise#81703
Original PR description
Inverse the domain on `subscription_state` from: `not in (selection_values)` -> `in (complement(selection_values))` Using the `in` operator gives Postgres the possibility to use an index on `subscription_state`, which cannot be done with a `not in` domain operator for `Selection` fields. Forward-Port-Of: odoo/enterprise#81703
The test requires `stock_dropshipping` to be installed to have sense, but the condition set to avoid the test running without it was insufficient. Since it was only checking on a string in the database, it wouldn't raise a ValueError, but just not find any matching record, thus running the test even without the module installed. Forward-Port-Of: odoo/enterprise#81981
Original PR description
The test requires `stock_dropshipping` to be installed to have sense, but the condition set to avoid the test running without it was insufficient. Since it was only checking on a string in the database, it wouldn't raise a ValueError, but just not find any matching record, thus running the test even without the module installed. Forward-Port-Of: odoo/enterprise#81981
### Steps to reproduce: - Install "l10n_mx_edi" and switch to Mexican company - In Accounting > Configuration > Taxes create a new tax with "Factor Type" set to "Cuota" - Create an invoice with this tax - Click "Send", select "CFDI" and send - Traceback ### Cause: Apparently a typo: The code tries to read `grouping_key['importe']` but `importe` is in the dictionary `tax_value` not `grouping_key`. ### Solution: Change `grouping_key` to `tax_value`. opw-4594061 Forward-Port-Of: o
Original PR description
### Steps to reproduce: - Install "l10n_mx_edi" and switch to Mexican company - In Accounting > Configuration > Taxes create a new tax with "Factor Type" set to "Cuota" - Create an invoice with this tax - Click "Send", select "CFDI" and send - Traceback ### Cause: Apparently a typo: The code tries to read `grouping_key['importe']` but `importe` is in the dictionary `tax_value` not `grouping_key`. ### Solution: Change `grouping_key` to `tax_value`. opw-4594061 Forward-Port-Of: odoo/enterprise#81328
This commit adds a test to make sure the progress bar of employee fetched in gantt view of attendance returns the expected values without any issue. opw-4492625 Forward-Port-Of: odoo/enterprise#82125 Forward-Port-Of: odoo/enterprise#82068
Original PR description
This commit adds a test to make sure the progress bar of employee fetched in gantt view of attendance returns the expected values without any issue. opw-4492625 Forward-Port-Of: odoo/enterprise#82125 Forward-Port-Of: odoo/enterprise#82068
Issue: ------ When migrating a database having 'Documents' module installed and also having empty/blank spreadsheets created in version saas-17.2 or lower will lead to a JSON decoder error. This happens when the 'spreadsheet_data' value become an empty `b''` because of empty spreadsheets. Here : https://github.com/odoo/enterprise/blob/17.0/spreadsheet_edition/models/spreadsheet_mixin.py#L224 Solution: ----------- Passing an empty dictionay '{}' if it gets empty quotes as `b''` during pr
Original PR description
Issue: ------ When migrating a database having 'Documents' module installed and also having empty/blank spreadsheets created in version saas-17.2 or lower will lead to a JSON decoder error. This…
Issue:
------
When migrating a database having 'Documents' module installed and also having empty/blank spreadsheets created in version saas-17.2 or lower will lead to a JSON decoder error. This happens when the 'spreadsheet_data' value become an empty `b''` because of empty spreadsheets.
Here :
https://github.com/odoo/enterprise/blob/17.0/spreadsheet_edition/models/spreadsheet_mixin.py#L224
Solution:
-----------
Passing an empty dictionay '{}' if it gets empty quotes as `b''` during processing.
Steps to reproduce:
------------------------
1. Create a database in version 17.2 or lower and install Documents module.
2. Create empty/blank spreadsheets (we can manually upload an empty spreadsheet).
3. Migrate the database to version saas~17.4 or above.
4. Finally, during testcases one of the test case will fail. Because of empty quotes.
Traceback:
```
File "/home/odoo/src/enterprise/saas-17.4/spreadsheet_edition/models/spreadsheet_mixin.py", line 44, in _compute_current_revision_uuid
snapshot = spreadsheet._get_spreadsheet_snapshot()
File "/home/odoo/src/enterprise/saas-17.4/spreadsheet_edition/models/spreadsheet_mixin.py", line 234, in _get_spreadsheet_snapshot
return json.loads(self.spreadsheet_data)
File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```
UPG - 2263261
TBG - 1416
Forward-Port-Of: odoo/enterprise#76211
Forward-Port-Of: odoo/enterprise#74685Issue ===== When validating an uncompleted return in Barcode, an error is raised. How to reproduce ================ - Open Barcode app > Operations > Receipts and create a new receipt; - Scan at least two times the same product's barcode; - Validate. - Re-open the same receipt and click on "Return Products"; - Scan one product then validate -> The return is correctly validated but an "Invalid Operation" error is raised. Cause of the issue ================== The return's move is d
Original PR description
Issue ===== When validating an uncompleted return in Barcode, an error is raised. How to reproduce ================ - Open Barcode app > Operations > Receipts and create a new receipt; - Scan at…
Issue ===== When validating an uncompleted return in Barcode, an error is raised. How to reproduce ================ - Open Barcode app > Operations > Receipts and create a new receipt; - Scan at least two times the same product's barcode; - Validate. - Re-open the same receipt and click on "Return Products"; - Scan one product then validate -> The return is correctly validated but an "Invalid Operation" error is raised. Cause of the issue ================== The return's move is done but `_split` is called and calling this method on a done move is forbidden. How to fix ========== In the `split_uncompleted_moves` move's method, done and cancel move are skipped. Also, the JS method who call `post_barcode_process` will now doesn't call it if operation is done or cancelled or if there is no moves (to avoid to do useless RPC.) [OPW-4535205](https://www.odoo.com/odoo/project/49/tasks/4535205) [OPW-4535257](https://www.odoo.com/odoo/project/49/tasks/4535257) Forward-Port-Of: odoo/enterprise#81829 Forward-Port-Of: odoo/enterprise#81312
Reproducing the issue in the database currently requires a real digital DIAN certificate. However, it can be tested in Python: - Create a credit note for a CO company with a foreign currency. - Generate the XML report. The tags SourceCurrencyBaseRate and CalculationRate are being added with a negative sign, but the DIAN only accepts positive values. This commit replace the locally computed rate with the account_move invoice_currency_rate (which meant correcting a few already existing t
Original PR description
Reproducing the issue in the database currently requires a real digital DIAN certificate. However, it can be tested in Python: - Create a credit note for a CO company with a foreign currency. - Generate the XML report. The tags SourceCurrencyBaseRate and CalculationRate are being added with a negative sign, but the DIAN only accepts positive values. This commit replace the locally computed rate with the account_move invoice_currency_rate (which meant correcting a few already existing test because of decimal accuracy differences) opw-4608444 Forward-Port-Of: odoo/enterprise#80850
With the PR [1] added test case which is failing in no demo mode (see [2]). This commit will ensure the test case will completely run witth no demo mode. [1] https://github.com/odoo/enterprise/pull/77334 [2] https://runbot.odoo.com/runbot/build/76189941 Forward-Port-Of: odoo/enterprise#80969
Original PR description
With the PR [1] added test case which is failing in no demo mode (see [2]). This commit will ensure the test case will completely run witth no demo mode. [1] https://github.com/odoo/enterprise/pull/77334 [2] https://runbot.odoo.com/runbot/build/76189941 Forward-Port-Of: odoo/enterprise#80969
Steps to reproduce: 1. In the Documents settings, activate the Recruitment option 2. Configure the "share" settings of the folder so internal users can view documents 3. In the recruitment app, add some attachments to the applications 4. Check these attachments' visibility -> They are not visible to internal users Technical Reason: The previous implementation ignored the recruitment folder’s access settings and set default access to 'none'. After this commit: documents inherit access
Original PR description
Steps to reproduce: 1. In the Documents settings, activate the Recruitment option 2. Configure the "share" settings of the folder so internal users can view documents 3. In the recruitment app, add some attachments to the applications 4. Check these attachments' visibility -> They are not visible to internal users Technical Reason: The previous implementation ignored the recruitment folder’s access settings and set default access to 'none'. After this commit: documents inherit access settings from the recruitment folder Task-4529233 Forward-Port-Of: odoo/enterprise#81705 Forward-Port-Of: odoo/enterprise#79544
Steps to reproduce: === - Install point_of_sale. - pos_online_payment is auto-installed. - Uninstall pos_online_payment. - Install pos_urban_piper. - Installation fails with an XPath error. Issue: === - XPath targeting is_online_payment is not found when pos_online_payment is uninstalled. Fix: === - Replaced XPath from is_online_payment to split_transactions to ensure proper installation. task-4639074 Forward-Port-Of: odoo/enterprise#80944
Original PR description
Steps to reproduce: === - Install point_of_sale. - pos_online_payment is auto-installed. - Uninstall pos_online_payment. - Install pos_urban_piper. - Installation fails with an XPath error. Issue: === - XPath targeting is_online_payment is not found when pos_online_payment is uninstalled. Fix: === - Replaced XPath from is_online_payment to split_transactions to ensure proper installation. task-4639074 Forward-Port-Of: odoo/enterprise#80944
Following this commit : - Initially for image_1920 in the product form view `options` was passed as `convert_to_webp': True`. - Since whenever the image is been uploaded irrespective of any format (.jpeg, .png) it will be converted to .webp which is not supported by Urban Piper. - So for pos_urban_piper this option is been modified and made False. task-4658346 Forward-Port-Of: odoo/enterprise#82044
Original PR description
Following this commit : - Initially for image_1920 in the product form view `options` was passed as `convert_to_webp': True`. - Since whenever the image is been uploaded irrespective of any format (.jpeg, .png) it will be converted to .webp which is not supported by Urban Piper. - So for pos_urban_piper this option is been modified and made False. task-4658346 Forward-Port-Of: odoo/enterprise#82044