Wednesday, June 4, 2025
30 changes · master
Enhancements to existing features
This update makes shared editor functionality easier to reuse across the website and backend by removing duplicate technical code and adjusting editor asset dependencies. It helps frontend features load the right editor tools more consistently, including point-of-sale appointment pages.
Original PR description
There are multiple duplicates of the `uuid` function, presumably because it is sometimes needed in frontend and was defined in `/web/views`. Update the usage of the function to import it from `/web/core` Adapt `pos_appointment` manifest after the `html_editor.assets_editor` was updated to be importable with `assets_frontend` task-4801746
This change updates internal tests for WhatsApp-related discussion channel behavior to stay aligned with recent platform changes. It helps maintain reliability and reduce the risk of regressions without changing day-to-day user workflows.
Original PR description
PR community: https://github.com/odoo/odoo/pull/212671 task-4829587
Resolved issues and error corrections
After a user signs a document, closing the confirmation popup now sends them back to the correct signed-document page instead of the general portal page. This avoids confusion when viewing completed signature requests, especially in cases where internal request identifiers differ.
Original PR description
### Before this commit: When closing the popup after signing a document, it redirects to the `/my` page instead of `/my/signature/<id>`. It only happens when the request's id is out-of-sync with the request item's id. ### After this commit: Correctly use the `sign.request.item`'s id, as expected from the `/my/signature` route.
Miscellaneous changes
Forward-Port-Of: odoo/enterprise#86948 Forward-Port-Of: odoo/enterprise#86889
Original PR description
Forward-Port-Of: odoo/enterprise#86948 Forward-Port-Of: odoo/enterprise#86889
Opening a report in Studio that has no linked view now shows a controlled user-facing error instead of causing a system traceback. This prevents confusing crashes for users managing reports and improves reliability in the report editor.
Original PR description
Here, when we try to open a report that is not linked to view, a traceback appears. **Steps to reproduce:** - Install the `stock` and `web_studio` modules. - Navigate to `Settings > Technical >…
Here, when we try to open a report that is not linked to view, a traceback appears. **Steps to reproduce:** - Install the `stock` and `web_studio` modules. - Navigate to `Settings > Technical > Actions > Reports`. - Create a new report (e.g; **Model Name** = product.template, **Template Name** = product.report_test). - Open the report in the web editor. **Error:** `ValueError: External ID not found in the system: studio_customization.studio_report_docume_product_label` In this case, if no view is defined for the report, the system attempts to retrieve the related view from [1]. However, since the view does not exist, it raises a **ValueError**. [1] - https://github.com/odoo/odoo/blob/924aa8aa2abe7765d2d605dc7643d1102e056fd6/odoo/addons/base/models/ir_ui_view.py#L2151 This behavior is already handled in **version 16.0** by [2] with a controlled exception. This commit adopts the same approach by raising **UserError** when no view is defined for a report, preventing an unhandled exception. [2] - https://github.com/odoo/enterprise/blob/511781a6bfb52c88892a54e43133b90ddfddbe22/web_studio/controllers/report.py#L137-L143 Related Community PR: https://github.com/odoo/odoo/pull/208806 Sentry - 5715762959, 6303192517, 6577830303, 6577830303, 6577830303, 6303950186
This update fixes several small Shop Floor issues so manufacturing and work order cards show the right names, work centers, product details, and company-related information. It also removes an unused employee popup component, reducing clutter without changing current workflows.
Original PR description
This PR fixes small issues regarding changes done here: odoo/enterprise#83203 and removes dead code.
Receipt header was never shown Steps to reproduce: ------------------- * Install l10n_cl_edi_pos * Open PoS * Make a sale that you invoice > Observation: The receipt is not showing the header with RUT Why the fix: ------------ The original `cl_vat` variable did not exist anymore. It was previously just mapping the company vat. So we use the company vat directly. opw-4784899 Forward-Port-Of: odoo/enterprise#86773 Forward-Port-Of: odoo/enterprise#85520
Original PR description
Receipt header was never shown Steps to reproduce: ------------------- * Install l10n_cl_edi_pos * Open PoS * Make a sale that you invoice > Observation: The receipt is not showing the header with RUT Why the fix: ------------ The original `cl_vat` variable did not exist anymore. It was previously just mapping the company vat. So we use the company vat directly. opw-4784899 Forward-Port-Of: odoo/enterprise#86773 Forward-Port-Of: odoo/enterprise#85520
See commit messages Forward-Port-Of: odoo/enterprise#86286
Original PR description
See commit messages Forward-Port-Of: odoo/enterprise#86286
Forward-Port-Of: odoo/enterprise#82967
Original PR description
Forward-Port-Of: odoo/enterprise#82967
In version 18.0, a traceback occurs when editing the 'Appointment: Attendee Invitation' email template and then signing up for an appointment. **Steps to reproduce:** 1. Go to **Appointments**. 2. Click the **"Action"** gear icon next to an appointment, then select **Edit**. 3. Navigate to the **Options** tab. 4. Hover over the **Booking Email** template and click the **arrow icon** to open it. 6. In the Content tab, add some text near "Hello", then click **Save**. 7. Return to t
Original PR description
In version 18.0, a traceback occurs when editing the 'Appointment: Attendee Invitation' email template and then signing up for an appointment. **Steps to reproduce:** 1. Go to **Appointments**. 2.…
In version 18.0, a traceback occurs when editing the 'Appointment:
Attendee Invitation' email template and then signing up for an
appointment.
**Steps to reproduce:**
1. Go to **Appointments**.
2. Click the **"Action"** gear icon next to an appointment, then select **Edit**.
3. Navigate to the **Options** tab.
4. Hover over the **Booking Email** template and click the **arrow icon** to open
it.
6. In the Content tab, add some text near "Hello", then click **Save**.
7. Return to the **Appointment form**
8. Click the "**Go to Website**" smart button at the top
9. Select a date and time.
10. Confirm the appointment.
This raises a traceback
**In saas-18.3**, editing the `Appointment: Attendee Invitation` email
template throws an error when saving, making the template uneditable.
**Issue:**
The issue originates from this [commit](https://github.com/odoo/enterprise/commit/8b9a1a4462453bf64e7bc1307ededd0d127a27fa), which introduced a
`<div>` inside a `<p>` — a structure that violates the HTML specification.
Editing anything near the word 'Hello' in the template causes the
`<p>` tag to close prematurely during rendering. This pushes the `<div>`
outside of the `<p>`, breaking the directive chain and resulting in
the following error:
> SyntaxError: t-elif directive must be preceded by t-if or t-elif directive
Previously, the `<div>` was also pushed outside the `<p>`, but only after
evaluating all `t-if, t-elif, and t-else` conditions. Hence, it worked
correctly without editing the template.
**Solution:**
Placed the `<span>` as a child of the `<p>` tag to resolve the issue.
This fix also resolves the issue of being unable to edit the template
"Appointment: Attendee Invitation" in the UI **on saas-18.3**.
[Task-4624645](https://www.odoo.com/odoo/project.task/project.task/4624645)
Forward-Port-Of: odoo/enterprise#85669Fix qty_delivered when a rental order is processed through the PoS. This commit ensure that the PoS qty_delivered computation is done after the other calculation Steps to reproduce: ------------------- * Make a rental for 1 product * Open the sale order in PoS * Pay for the rental > Observation: The qty_delivered is set to 2 instead of 1 on the rental Why the fix: ------------ When the order is a rental processed through the PoS, we recompute the rental qty and add the PoS quantity
Original PR description
Fix qty_delivered when a rental order is processed through the PoS. This commit ensure that the PoS qty_delivered computation is done after the other calculation Steps to reproduce: ------------------- * Make a rental for 1 product * Open the sale order in PoS * Pay for the rental > Observation: The qty_delivered is set to 2 instead of 1 on the rental Why the fix: ------------ When the order is a rental processed through the PoS, we recompute the rental qty and add the PoS quantity to make sure that the value is correct. The computation is actually just the fusion of the PoS and rental _compute_qty_delivered methods. opw-4582505 Forward-Port-Of: odoo/enterprise#86317 Forward-Port-Of: odoo/enterprise#84768
The "Fetch from CodaBox" link displayed on the accounting dashboard had no gap between it and the button at the left of it, and wasn't aligned horizontaly with the other buttons next to it making it look out of place. It is now displayed as a link button, which solve both problems. task-4671468 Purpose The fetch from CodaBox is too sticky to the upload button  After this commit :  After this commit :  Forward-Port-Of: odoo/enterprise#84858
**Steps to reproduce**: 1. Install Appraisals 2. Appraisals > Open any Employee card 3. Turn on the debug mode 4. Click on Debug Icon 5. Click Data **Issue**: - A Traceback error occurs when trying to read the record. - The fields parameter is None in some cases (viewing Raw Record data in Debug mode) in read function, leading to an attempt to convert it to an empty dictionary, which is not iterable. **Cause**: - The read() function was called with fields is None in debug mod
Original PR description
**Steps to reproduce**:
1. Install Appraisals
2. Appraisals > Open any Employee card
3. Turn on the debug mode
4. Click on Debug Icon
5. Click Data
**Issue**:
- A Traceback error occurs when trying to read the record.
- The fields parameter is None in some cases (viewing Raw Record data in Debug mode) in read function, leading to an
attempt to convert it to an empty dictionary, which is not iterable.
**Cause**:
- The read() function was called with fields is None in debug mode and it was incorrectly converting None to {}, causing a
TypeError when performing set operations.
**Solution**:
- Instead of setting None to {}, it should be converted to an empty set to avoid type mismatch.
opw-4788901
Forward-Port-Of: odoo/enterprise#85876If one uploads a vendor bill from the list view using the "Upload" button, a banner is then shown on the form view of the created move to reload the data that were extracted via IAP. However, this banner is not shown if one creates an empty move, then uploads via the attachments, then the banner is never shown. This is because when we arrive in the `onWillStart` of the `StatusHeader`, we subscribe to a channel using the `extract_document_uuid` which does not exist upon creating a new empty
Original PR description
If one uploads a vendor bill from the list view using the "Upload" button, a banner is then shown on the form view of the created move to reload the data that were extracted via IAP. However, this…
If one uploads a vendor bill from the list view using the "Upload" button, a banner is then shown on the form view of the created move to reload the data that were extracted via IAP.
However, this banner is not shown if one creates an empty move, then uploads via the attachments, then the banner is never shown.
This is because when we arrive in the `onWillStart` of the `StatusHeader`, we subscribe to a channel using the `extract_document_uuid` which does not exist upon creating a new empty move. Then, when we upload our document, the move record is saved, and is sent to the backend. At this point, the move exists, and a `extract_document_uuid` is set. Then we get the OCR results (in `_check_ocr_status`) and we have a new status, we send this status on the bus but on a channel named `f"extract.mixin.status#{self.extract_document_uuid}"` where the `extract_document_uuid` is set. However, in the JS part, it was empty because it was created in the `onWillStart`.
To resolve this, we create a new channel to detect newly created documents. We send the new `extract_document_uuid` in this channel from the backend to the frontend. The JS can now subscribe to the correct channel using an existing `extract_document_uuid`.
Now, correctly the JS receives the updates of the Python via the bus, and can update the view accordingly.
opw-4566944
Forward-Port-Of: odoo/enterprise#83522When multiple taxes are configured on the "WORK IN" and "WORK OUT" products (a common scenario in a multi-company setup), the check for the tax amount would fail. The previous code attempted to access the `amount` field directly on a multi-record tax recordset, which results in an error. This caused the Point of Sale session to fail on opening. opw-4744514 Forward-Port-Of: odoo/enterprise#86807
Original PR description
When multiple taxes are configured on the "WORK IN" and "WORK OUT" products (a common scenario in a multi-company setup), the check for the tax amount would fail. The previous code attempted to access the `amount` field directly on a multi-record tax recordset, which results in an error. This caused the Point of Sale session to fail on opening. opw-4744514 Forward-Port-Of: odoo/enterprise#86807
Currently, when a user sends an article to the trash, the system triggers a notification email to relevant members informing them that the article has been trashed and will be permanently deleted in 30 days (see: `knowledge_article_trash_notification`). This email includes a link to the trashed article (see: `article_url`). However, when a user clicks the link, they are taken to a 403 error page and cannot access the article to review or restore it. Steps to reproduce the issue: 1. Open a
Original PR description
Currently, when a user sends an article to the trash, the system triggers a notification email to relevant members informing them that the article has been trashed and will be permanently deleted in…
Currently, when a user sends an article to the trash, the system triggers a notification email to relevant members informing them that the article has been trashed and will be permanently deleted in 30 days (see: `knowledge_article_trash_notification`). This email includes a link to the trashed article (see: `article_url`). However, when a user clicks the link, they are taken to a 403 error page and cannot access the article to review or restore it. Steps to reproduce the issue: 1. Open an article 2. Send the article to the trash 3. Open the notification email and click on the article link => The user is redirected to a 403 error page When an article is trashed (see: `action_send_to_trash`), it is marked as inactive. As a result, it is excluded from ORM search results by default. The `/knowledge/article/<id>` route uses the ORM to retrieve the article by its ID. Since trashed articles are inactive, the ORM does not return the article, leading the route to assume the article does not exist and redirect the user to a 403 error page. To resolve this issue, we will modify the context of the search method to include the key `active_test=False`. This will allow the ORM to return inactive (trashed) articles. As a result, users who follow the link from the email will be correctly redirected to the trashed article page, where they can view its content and choose to restore it using the banner interface. Task-4636494 Forward-Port-Of: odoo/enterprise#86065
When you are in a list view, you can select multiple records by clicking the checkbox. But if after selecting multiple records, you click on a line, it will only select the record you just clicked and all other preselected records will be ignored. This commit change that, as now if you already have selected records, if you clik on a line without checking the checkbox, it will add the record to the selection just like you clicked on the checkbox. task-4816580 Forward-Port-Of: odoo/enterpri
Original PR description
When you are in a list view, you can select multiple records by clicking the checkbox. But if after selecting multiple records, you click on a line, it will only select the record you just clicked and all other preselected records will be ignored. This commit change that, as now if you already have selected records, if you clik on a line without checking the checkbox, it will add the record to the selection just like you clicked on the checkbox. task-4816580 Forward-Port-Of: odoo/enterprise#86630
This commit enable the upload features in the bank rec widget if the journal is not in synchronisation mode or Codabox. To do so, we use the "bank_statements_source" field in the context keys. task-4809006 Forward-Port-Of: odoo/enterprise#86526
Original PR description
This commit enable the upload features in the bank rec widget if the journal is not in synchronisation mode or Codabox. To do so, we use the "bank_statements_source" field in the context keys. task-4809006 Forward-Port-Of: odoo/enterprise#86526
The `action_timer_start` method caused infinite recursion when the user's timezone differed from the timesheet's timezone. The comparison between `fields.Date.today()` and `self.date` failed, creating a new timesheet. That new timesheet triggered `action_timer_start` again, repeating the loop. **Steps to Produce:-** 1. Install the `Timesheets` application. 2. Navigate to `Settings > Users & Companies > User`. 3. Select your current user and, under `Preferences`, set the timezone to one t
Original PR description
The `action_timer_start` method caused infinite recursion when the user's timezone differed from the timesheet's timezone. The comparison between `fields.Date.today()` and `self.date` failed,…
The `action_timer_start` method caused infinite recursion when the user's timezone differed from the timesheet's timezone. The comparison between `fields.Date.today()` and `self.date` failed, creating a new timesheet. That new timesheet triggered `action_timer_start` again, repeating the loop.
**Steps to Produce:-**
1. Install the `Timesheets` application.
2. Navigate to `Settings > Users & Companies > User`.
3. Select your current user and, under `Preferences`, set the timezone to one that does not reflect today’s date.
4. Open the Timesheets application, and for any record, click on the `Search icon` in the column for today’s date.
5. Start the time tracking by clicking the `Play button`.
6. Wait for a moment; an error will generate.
**Error:-**
`RecursionError: maximum recursion depth exceeded.`
**Solution:-**
- When action_timer_start() is invoked, it first checks for the _from_action_timer flag in the context.
- If not set, it sets _from_action_timer=True.
- The next time action_timer_start() is triggered, the presence of _from_action_timer in the context causes it to exit early,
preventing recursion.
**Sentry - 6592348827**
Forward-Port-Of: odoo/enterprise#85105Currently, an error-level log is generated when confirming a Vendor Bill without setting the required AFIP Authorization Code. **Steps to Reproduce:** 1) Install `l10n_ar_edi module`. 2) Select Company having Argentina code (e.g **(AR)Exento**) 3) Navigate to `Invoicing->Configuration->settings`, under Argentina localization, set `Verify Vendor Bills validity in AFIP` to **required**. 4) Create a new Vendor Bill, select Vendor Name (e.g **ADHOC SA**). 5) Click on confirm. **Error
Original PR description
Currently, an error-level log is generated when confirming a Vendor Bill without setting the required AFIP Authorization Code. **Steps to Reproduce:** 1) Install `l10n_ar_edi module`. 2) Select…
Currently, an error-level log is generated when confirming a Vendor Bill without setting the required AFIP Authorization Code.
**Steps to Reproduce:**
1) Install `l10n_ar_edi module`.
2) Select Company having Argentina code (e.g **(AR)Exento**)
3) Navigate to `Invoicing->Configuration->settings`, under Argentina localization,
set `Verify Vendor Bills validity in AFIP` to **required**.
4) Create a new Vendor Bill, select Vendor Name (e.g **ADHOC SA**).
5) Click on confirm.
**Error:**
UserError('Please set AFIP Authorization Mode and Code to continue!')
**Root Cause:**
- The code calls `_logger.error(repr(error))` on any exception at [1] during the AFIP verification attempt, causing an ERROR‐level log entry.
[1]- https://github.com/odoo/enterprise/blob/ca16c89c6f53b1c0adb0a1a061d985bdf3439e5e/l10n_ar_edi/models/account_move.py#L500
**Solution:**
- This commit handles `UserError` exceptions separately using a warning log to prevent error-level entries.
Sentry-6576006813
Forward-Port-Of: odoo/enterprise#85261This commit fixes a traceback that happens when someone opens a pos config with a belgian blackbox configured. The traceback is caused by the _notify "CLOCKING" where the "_" fields are not sent. Forward-Port-Of: odoo/enterprise#86884
Original PR description
This commit fixes a traceback that happens when someone opens a pos
config with a belgian blackbox configured. The traceback is caused by
the _notify "CLOCKING" where the "_" fields are not sent.
Forward-Port-Of: odoo/enterprise#86884**Current behavior before PR:** The composer automatically selects all its text when focused. This behavior is only expected in threads where the channel type is `ai_composer` but currently applies to all threads. **Desired behavior after PR is merged:** The automatic text selection happens only in threads where the channel type is `ai_composer`. Other composers remain unaffected and behave normally. Forward-Port-Of: odoo/enterprise#86745
Original PR description
**Current behavior before PR:** The composer automatically selects all its text when focused. This behavior is only expected in threads where the channel type is `ai_composer` but currently applies to all threads. **Desired behavior after PR is merged:** The automatic text selection happens only in threads where the channel type is `ai_composer`. Other composers remain unaffected and behave normally. Forward-Port-Of: odoo/enterprise#86745
#PURPOSE: - Currently is the user is promoted as admin for accounting and he/she is try to generate/regenerate or view the gst report following Error is thrown. - Access Error ```Uh-oh! Looks like you have stumbled upon some top-secret records. Sorry, Marc Demo (id=5) doesn't have 'read' access to: - Document (documents.document)``` #STEPS TO REPRODUCE 1) Install necessary modules for indian accounting localization. 2) Enable GST E-Filing & Matching Fe
Original PR description
#PURPOSE: - Currently is the user is promoted as admin for accounting and he/she is try to generate/regenerate or view the gst report following Error is thrown. - Access Error ```Uh-oh! Looks like…
#PURPOSE:
- Currently is the user is promoted as admin for accounting and he/she is try
to generate/regenerate or view the gst report following Error is thrown.
- Access Error
```Uh-oh! Looks like you have stumbled upon some top-secret records.
Sorry, Marc Demo (id=5) doesn't have 'read' access to:
- Document (documents.document)```
#STEPS TO REPRODUCE
1) Install necessary modules for indian accounting localization.
2) Enable GST E-Filing & Matching Feature from account's configuration.
3) Go to Settings -> User & Companies -> Users
4) Click new if no user is there other then administrator else click on
another user.
5) Under Access Rights section , inside Accounting select Administrator & Save.
6) Now log in as new user in another tab.
7) Go to Accounting -> Reporting under 'India' section click on
GST Return Period.
8) Click on generate/regenerate or View option.
9) The above shown error will be raised.
#SPECIFICATION:
- The issue is with documents access rights
- After promoting user to admin of accounting, the document's folder right is
not properly assign to user.
- fix this by giving rights of GSTR folder to user if user is in accounting
manager group.
task-4770583
Forward-Port-Of: odoo/enterprise#86660
Forward-Port-Of: odoo/enterprise#84747When Acerta Affiliation Number is unset and user tries to generate export file, A traceback will appear. Steps to reproduce the error: - Install ``l10n_be_hr_payroll_acerta`` module and switch to belgian company - Create an employee A > Create a contract(Status: Running) for that employee A > Details > Set Acerta code > save - Go to Payroll > Configuration > Settings > Unset Acerta Affiliation Number - Go to Payroll > Reporting > Export Work Entries to Acerta > New > Populate > Click
Original PR description
When Acerta Affiliation Number is unset and user tries to generate export file, A traceback will appear. Steps to reproduce the error: - Install ``l10n_be_hr_payroll_acerta`` module and switch to…
When Acerta Affiliation Number is unset and user tries to generate export file,
A traceback will appear.
Steps to reproduce the error:
- Install ``l10n_be_hr_payroll_acerta`` module and switch to belgian company
- Create an employee A > Create a contract(Status: Running) for that employee A >
Details > Set Acerta code > save
- Go to Payroll > Configuration > Settings > Unset Acerta Affiliation Number
- Go to Payroll > Reporting > Export Work Entries to Acerta > New > Populate > Click on Generate Export File button
Traceback:
```
File "/home/odoo/src/enterprise/l10n_be_hr_payroll_acerta/models/hr_payroll_export_acerta.py", line 45, in _generate_line
return 'KLX1' + self.company_id.acerta_code + contract.acerta_code.zfill(20) \
TypeError: can only concatenate str (not "bool") to str
```
https://github.com/odoo/enterprise/blob/a4f68967a9826fac981c1141ece1791a0baf647a/l10n_be_hr_payroll_acerta/models/hr_payroll_export_acerta.py#L45
When ``self.company_id.acerta_code`` is not set,
It will lead to the above traceback.
sentry-6620429585
Forward-Port-Of: odoo/enterprise#86098Currently, sending an invoice can raise an error if the **Electronic Invoice Type** is not set on the invoice. **Steps to Reproduce:** - Install the `l10n_co_dian` module. - Change the default company to **CO Company**. - Create and confirm a customer invoice, but leave the **Electronic Invoice Type** unset. - Send the invoice. **Error:** `AttributeError - 'bool' object has no attribute 'rjust'` Here, an issue occurs because the system attempts to call `rjust()` on the field `l10n_
Original PR description
Currently, sending an invoice can raise an error if the **Electronic Invoice Type** is not set on the invoice. **Steps to Reproduce:** - Install the `l10n_co_dian` module. - Change the default company to **CO Company**. - Create and confirm a customer invoice, but leave the **Electronic Invoice Type** unset. - Send the invoice. **Error:** `AttributeError - 'bool' object has no attribute 'rjust'` Here, an issue occurs because the system attempts to call `rjust()` on the field `l10n_co_edi_type` without ensuring it is a string. When the field is `False`, it results in an Attribute error. - [1] This commit ensures the right access to `rjust()` only when `l10n_co_edi_type` is a valid string, preventing the error. [1] - https://github.com/odoo/enterprise/blob/8d7a13822e9fd480a6e279ff93e29834a6668536/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L974-L975 Sentry - 6622171121 Forward-Port-Of: odoo/enterprise#86769 Forward-Port-Of: odoo/enterprise#86211