Daily updates from Odoo
Friday, July 31, 2026
266 changes
15 changes
Enhancements to existing features
Previously, questions in the event template could not be reordered via drag-and-drop on the Questions page. Instead of adding the handle to the inline list embedded in the event.type form view, we add it to the dedicated event.question list view (event_question_view_list). This will allow the users to reorder from the event questions and the sequence will be synced everywhere those questions appear. Steps to reproduce: 1.Go to event, configurations, and event questions. 2.We can't drag an
Original PR description
Previously, questions in the event template could not be reordered via drag-and-drop on the Questions page. Instead of adding the handle to the inline list embedded in the event.type form view, we add it to the dedicated event.question list view (event_question_view_list). This will allow the users to reorder from the event questions and the sequence will be synced everywhere those questions appear. Steps to reproduce: 1.Go to event, configurations, and event questions. 2.We can't drag and drop questions Original PR (18.0): odoo/odoo#270576 opw-6260478 Forward-Port-Of: odoo/odoo#277071
Resolved issues and error corrections
The Belgian minimum salary warning is now limited to employees under Belgian payroll rules. This prevents irrelevant salary alerts from appearing for employees in other countries, reducing confusion for payroll users.
Original PR description
[FIX] l10n_be: fix min salary warning appearance in other l18n Bug reproduc: 1 - Install l10n_be_hr_payroll 2 - Go to some US employee, make its wage to 10. 3 - The warning "Annual salary is below 34654" will be there. Bug cause: 1 - The issue is created without controlling the country of the version Bug solution: 1 - Add Belgium country check to the issue creation task-6412374 Forward-Port-Of: odoo/enterprise#125279
This fixes an automated test for Mexican point-of-sale invoicing by ensuring the original sale is fully synchronized before a refund is started. It helps keep refund and invoice validation reliable without changing the business workflow for users.
Original PR description
In this commit: =============== - Fix the `test_mx_pos_invoice_order_and_refund` tour, which fails with the warning: `The amount of the order must be positive for a sale and negative for a refund`. - The failure is caused by the refund flow starting before the original order has been fully synced with the backend. - A previous attempt to fix this in odoo/enterprise#109362 by waiting for `FeedbackScreen.isShown()` was not sufficient. Fix: ==== - Add a `Chrome.waitForOrdersSync()` waiting step to the tour to ensure the original order is fully synced before starting the refund flow. Error: 237980 Forward-Port-Of: odoo/enterprise#124948
The accounting reports now handle invoices linked to a tax that was originally a group of taxes but later changed. This prevents the Journal Report from failing, so users can continue reviewing audit reports even after tax configuration updates.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
This update corrects an automated payroll attendance test so it uses the right pay category and overtime unit setup. It helps ensure payroll overtime scenarios are validated reliably, reducing the risk of future payroll issues going unnoticed.
Original PR description
Set the employee's Pay Category to the test structure type, so the pay run finds a matching version, and create the overtime work entry type in hours. Also drops the leftover Continue step after the payslip is opened. task-6432271 Forward-Port-Of: odoo/enterprise#126219
Payroll decimal precision settings will no longer be reset to default values when the Payroll module is upgraded. This protects company-specific payroll rounding and rate precision customizations from being silently overwritten.
Original PR description
decimal.precision records are user-configurable settings that may be adjusted per company needs. With noupdate="0", every module upgrade resets the 'Payroll' and 'Payroll Rate' precision values back to their defaults, silently discarding any customization made by the user. This is inconsistent with the standard pattern used across Odoo modules. For example, the 'quality' module correctly loads its decimal.precision records with noupdate="1". The same convention is followed in core addons such as 'product' and 'account'. The forcecreate="True" attribute already ensures the records are created on fresh installations, so noupdate="1" only prevents overwriting existing values on upgrade — which is the expected behavior for configuration data. Forward-Port-Of: odoo/enterprise#120509
The online payment status now updates correctly when users move between batch payment records. This prevents outdated payment information from appearing, helping users see whether each batch payment has been signed or is still pending.
Original PR description
To display the `payment_online_status` field, we use a widget called `account_online_payment_refresh_button`. The issue is that the widget don't update the field value when switching from one record to another. Steps to reproduce: 1. Create 2 batch payments 2. Do a payment initiation with the first one, and sign it 3. Do another payment initiation with the second one, but don't sign it. 4. Open 1 batch, and try to switch records with the pager 5. You should see the value is not updated task-6420585 Forward-Port-Of: odoo/enterprise#126215 Forward-Port-Of: odoo/enterprise#125643
Polish JPK tax exports now use the supplier's bill reference in the purchase document field when one is provided. This makes exported tax files better match official reporting requirements and avoids showing the internal vendor bill number instead.
Original PR description
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting >…
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting > Reporting > Tax Report and select `This Month`. - From the dropdown, click `JPK` > `Export XML`. - Open the generated XML file and observe the `DowodZakupu` field. **Observation:** `DowodZakupu` contains the vendor `Bill Number` even when a `Bill Reference` is set. **Root Cause:** At [1], `DowodZakupu` is populated only with the vendor `Bill number`(`move_name`) instead of using the `Bill reference`(`ref`) when available. **Fix:** This commit ensures `DowodZakupu` contains the `Bill Reference` when it is available in JPK exports. **Reference:** https://www.podatki.gov.pl/media/eqrn3dey/broszura-jpk_vat-z-deklaracj%C4%85-od-1-lutego-2026-r-en.pdf (page 41) [1]: https://github.com/odoo/enterprise/blob/4b0404058b280136f6865090562f95e18d4d7e0b/l10n_pl_reports/data/jpk_export_templates.xml#L208 opw-6299827 Forward-Port-Of: odoo/enterprise#126113 Forward-Port-Of: odoo/enterprise#121117
This fix prevents a Knowledge automated tour from failing because of leftover collaboration state from a previous test. It improves the reliability of internal quality checks without changing how users interact with Knowledge.
Original PR description
This aims to fix Runbot build error #937788 ([1]) which wasn't fully fixed by commit [2] (see error #944595 ([3])). A collaboration error was thrown during a tour which makes no use of collaboration. Commit [2] made sure the bus from the previous test didn't persist when running this tour so it doesn't interfere, but it didn't fully reset it. [1]: https://runbot.odoo.com/odoo/runbot.build.error/937788 [2]: https://github.com/odoo/enterprise/commit/a6050dd60c587d09443907bdf955805159dbdb2e [3]: https://runbot.odoo.com/odoo/runbot.build.error/944595 Forward-Port-Of: odoo/enterprise#126195
A previous fix that only applied to an older version was incorrectly carried forward and could cause an error in the bank reconciliation quick create flow. This update removes that unsuitable change so the accounting workflow behaves correctly in this version.
Original PR description
This commit https://github.com/odoo/enterprise/commit/e559d9f5acbd176792db0dedc4e1f0cad7271457 fixed a problem only happening in 19.0. The commit shouldn't have been forward ported. no task id Forward-Port-Of: odoo/enterprise#126039
Bank reconciliation now shows the same supporting attachments in the list view as users already see in the kanban view. This reduces confusion and helps accounting teams access the right documents consistently during reconciliation.
Original PR description
The aim of this commit is showing the same attachment in the bank reconciliation list view than in the kanban view. Before this commit, the field used to display the attachments was attachment_ids, this field were a related on the attachment_ids from account.move. This fix, removes the related to only keep a domain on the One2Many field. Thanks to the relational database, Odoo is giving us the right attachments when we want to display the field. task-6153002 Forward-Port-Of: odoo/enterprise#117245
Steps: - Install portal app - Go to my/addresses page. - Update main address of current user. Issues: - `Main Address` badge is not visible on main address. - Editing main address is not opening `my/account` page. Cause: - Since PR https://github.com/odoo/odoo/pull/232539 t-call syntax changed and expect to add attribute directly instead t-set but forget to adept it for `is_user_address` and `address_update_url`. Fix: - Move those variable directly into t-call instead t-set. For
Original PR description
Steps: - Install portal app - Go to my/addresses page. - Update main address of current user. Issues: - `Main Address` badge is not visible on main address. - Editing main address is not opening `my/account` page. Cause: - Since PR https://github.com/odoo/odoo/pull/232539 t-call syntax changed and expect to add attribute directly instead t-set but forget to adept it for `is_user_address` and `address_update_url`. Fix: - Move those variable directly into t-call instead t-set. Forward-Port-Of: odoo/odoo#278812
Error-1 : ``` raise ValueError('External ID not found in the system: %s' % xmlid) ValueError: External ID not found in the system: account.1_l10n_id_domestic_fiscal_position ``` Error-2 : ``` raise ValueError('External ID not found in the system: %s' % xmlid) ValueError: External ID not found in the system: account.1_tax_luxury_sales ``` Reason-1 : - In [this](https://github.com/odoo/odoo/commit/e342a45aceb60b44052c5d52e9ecc35a9a7340da) commit new account.fiscal.positions were ad
Original PR description
Error-1 : ``` raise ValueError('External ID not found in the system: %s' % xmlid) ValueError: External ID not found in the system: account.1_l10n_id_domestic_fiscal_position ``` Error-2 : ``` raise…
Error-1 :
```
raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system:
account.1_l10n_id_domestic_fiscal_position
```
Error-2 :
```
raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: account.1_tax_luxury_sales
```
Reason-1 :
- In [this](https://github.com/odoo/odoo/commit/e342a45aceb60b44052c5d52e9ecc35a9a7340da) commit new account.fiscal.positions were added and linked to acc.tax using fiscal_position_ids .
- In [this](https://github.com/odoo/odoo/blob/saas-19.2/addons/l10n_id/migrations/1.3/end-migrate_update_taxes.py) migration script, while creating taxes it didnt find fiscal positions, so need to create them first.
Reason-2 :
- original_tax_ids was also added in same commit, if client deleted those tax(ie tax_luxury_sales) will fail while creating `tax_luxury_sales_pemungut_ppn`, It needs to be created first too.
- upg : [4341887](https://upgrade.odoo.com/odoo/upgrade.request/4341887)
- opw : [6285978](https://www.odoo.com/odoo/project/70/tasks/6285978)
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#269802Currently, an error occurs when installing the hr_holidays_attendance module. **Steps to Reproduce:** - Install the `hr_attendance` module without demo data. - Go to `Attendance` > `Configuration` > `Overtime Rulesets` and open the `Default Ruleset` record. - Delete its `linked overtime rules`. - Install the `hr_holidays_attendance` module. **Error:** ```py Exception: Cannot update missing record 'hr_attendance.hr_attendance_overtime_employee_schedule_rule' odoo.tools.conver
Original PR description
Currently, an error occurs when installing the hr_holidays_attendance module. **Steps to Reproduce:** - Install the `hr_attendance` module without demo data. - Go to `Attendance` > `Configuration` >…
Currently, an error occurs when installing the hr_holidays_attendance module.
**Steps to Reproduce:**
- Install the `hr_attendance` module without demo data.
- Go to `Attendance` > `Configuration` > `Overtime Rulesets` and open the `Default Ruleset` record.
- Delete its `linked overtime rules`.
- Install the `hr_holidays_attendance` module.
**Error:**
```py
Exception: Cannot update missing record 'hr_attendance.hr_attendance_overtime_employee_schedule_rule'
odoo.tools.convert.ParseError: while parsing /home/odoo/odoo18/community/addons/hr_holidays_attendance/data/hr_holidays_attendance_data.xml:7, somewhere inside <record id="hr_attendance.hr_attendance_overtime_employee_schedule_rule" model="hr.attendance.overtime.rule">
<field name="compensable_as_leave" eval="True"/>
</record>
```
This error occurs when the user deletes all overtime rules and then installs the hr_holidays_attendance
module. During installation, the module attempts to update the deleted overtime rule records,
which raises an error [1].
This commit uses forcecreate="0" to skip updating records if the corresponding overtime
rules do not exist.
[1]- https://github.com/odoo/odoo/blob/da0a83761f38ee4a2940015b6c8f7190c310a4a0/addons/hr_holidays_attendance/data/hr_holidays_attendance_data.xml#L7-L12
sentry-7372074675
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279088
Forward-Port-Of: odoo/odoo#277656Reading the `display_name` of a working schedule line of a 2 weeks calendar crashes: the compute reads `record.weektype` while the field is named `week_type`. ### Steps to reproduce - Switch a working schedule to a 2 weeks calendar. - Open one of its lines in a form view, e.g. with the `View Button` optional column in developer mode. opw-6427314 Forward-Port-Of: odoo/odoo#279194
Original PR description
Reading the `display_name` of a working schedule line of a 2 weeks calendar crashes: the compute reads `record.weektype` while the field is named `week_type`. ### Steps to reproduce - Switch a working schedule to a 2 weeks calendar. - Open one of its lines in a form view, e.g. with the `View Button` optional column in developer mode. opw-6427314 Forward-Port-Of: odoo/odoo#279194
12 changes
Enhancements to existing features
Previously, questions in the event template could not be reordered via drag-and-drop on the Questions page. Instead of adding the handle to the inline list embedded in the event.type form view, we add it to the dedicated event.question list view (event_question_view_list). This will allow the users to reorder from the event questions and the sequence will be synced everywhere those questions appear. Steps to reproduce: 1.Go to event, configurations, and event questions. 2.We can't drag an
Original PR description
Previously, questions in the event template could not be reordered via drag-and-drop on the Questions page. Instead of adding the handle to the inline list embedded in the event.type form view, we add it to the dedicated event.question list view (event_question_view_list). This will allow the users to reorder from the event questions and the sequence will be synced everywhere those questions appear. Steps to reproduce: 1.Go to event, configurations, and event questions. 2.We can't drag and drop questions Original PR (18.0): odoo/odoo#270576 opw-6260478 Forward-Port-Of: odoo/odoo#277071
Resolved issues and error corrections
This fix makes an automated test for Mexican point-of-sale invoicing wait until the original order is fully saved before testing a refund. It helps prevent false test failures, improving release reliability without changing day-to-day user workflows.
Original PR description
In this commit: =============== - Fix the `test_mx_pos_invoice_order_and_refund` tour, which fails with the warning: `The amount of the order must be positive for a sale and negative for a refund`. - The failure is caused by the refund flow starting before the original order has been fully synced with the backend. - A previous attempt to fix this in odoo/enterprise#109362 by waiting for `FeedbackScreen.isShown()` was not sufficient. Fix: ==== - Add a `Chrome.waitForOrdersSync()` waiting step to the tour to ensure the original order is fully synced before starting the refund flow. Error: 237980 Forward-Port-Of: odoo/enterprise#124948
Polish JPK tax exports now use the supplier's bill reference when it is provided, instead of defaulting to the internal vendor bill number. This helps companies produce tax files that better match supplier documents and official reporting expectations.
Original PR description
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting >…
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting > Reporting > Tax Report and select `This Month`. - From the dropdown, click `JPK` > `Export XML`. - Open the generated XML file and observe the `DowodZakupu` field. **Observation:** `DowodZakupu` contains the vendor `Bill Number` even when a `Bill Reference` is set. **Root Cause:** At [1], `DowodZakupu` is populated only with the vendor `Bill number`(`move_name`) instead of using the `Bill reference`(`ref`) when available. **Fix:** This commit ensures `DowodZakupu` contains the `Bill Reference` when it is available in JPK exports. **Reference:** https://www.podatki.gov.pl/media/eqrn3dey/broszura-jpk_vat-z-deklaracj%C4%85-od-1-lutego-2026-r-en.pdf (page 41) [1]: https://github.com/odoo/enterprise/blob/4b0404058b280136f6865090562f95e18d4d7e0b/l10n_pl_reports/data/jpk_export_templates.xml#L208 opw-6299827 Forward-Port-Of: odoo/enterprise#126113 Forward-Port-Of: odoo/enterprise#121117
This fix prevents the Accounting journal report from crashing when an invoice refers to a tax that was previously configured as a group of taxes and later changed. Users can continue generating audit reports even when historical tax setup changes leave older entries with missing group details.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
Payroll decimal precision settings are now treated as user-configurable data, so module upgrades no longer reset customized values to defaults. This helps companies keep their payroll calculation preferences intact after updates.
Original PR description
decimal.precision records are user-configurable settings that may be adjusted per company needs. With noupdate="0", every module upgrade resets the 'Payroll' and 'Payroll Rate' precision values back to their defaults, silently discarding any customization made by the user. This is inconsistent with the standard pattern used across Odoo modules. For example, the 'quality' module correctly loads its decimal.precision records with noupdate="1". The same convention is followed in core addons such as 'product' and 'account'. The forcecreate="True" attribute already ensures the records are created on fresh installations, so noupdate="1" only prevents overwriting existing values on upgrade — which is the expected behavior for configuration data. Forward-Port-Of: odoo/enterprise#120509
This update corrects an automated payroll attendance test so it uses the right pay category and overtime setup. It helps ensure payroll overtime scenarios are validated reliably without affecting day-to-day users.
Original PR description
Set the employee's Pay Category to the test structure type, so the pay run finds a matching version, and create the overtime work entry type in hours. Also drops the leftover Continue step after the payslip is opened. task-6432271
This change removes a fix that was only relevant to an earlier Odoo version and caused problems after being carried forward. Bank reconciliation quick-create behavior is restored for this release, reducing the risk of unexpected errors for accounting users.
Original PR description
This commit https://github.com/odoo/enterprise/commit/e559d9f5acbd176792db0dedc4e1f0cad7271457 fixed a problem only happening in 19.0. The commit shouldn't have been forward ported. no task id Forward-Port-Of: odoo/enterprise#126039
Ecuadorian invoice printouts now show the company logo in the header again. The header layout was slightly adjusted so the logo and invoice details fit correctly on the existing page format.
Original PR description
### Issue: In 19.3, the EC invoice header completely replaces the standard header in `report_invoice_document` after commit `08d17cc49c` The company logo was not included in the custom header, leaving invoices without a logo ### Cause: The logo was simply missing from the header template ### Fix: The logo is added and some header elements are resized (`h5` → `h6`, reduced margin) to keep the layout within the existing paper format without requiring a new one ### Steps to reproduce: - Install `l10n_ec_edi` with demo data - Open and print any invoice Before the fix, the company logo is missing from the header opw-6377830
Basic document users can now open the spreadsheet creation window even when they do not have access to spreadsheet templates. This removes an unnecessary blocker and lets them create empty spreadsheets from the Documents app like other document types.
Original PR description
A basic user can access the document app and create all types of documents from the kanban view except for the spreadsheets because it requires an access to the templates. While the user cannot interact with the templates, they should have the possibility to create an empty spreadsheet. Note that it can already be done coming from the view of a spreadsheet! This revision ensures that the user can indeed access the spreadsheet creation modal even if they don't have access to the spreadsheet templates. Task-6364964 Forward-Port-Of: odoo/enterprise#126231 Forward-Port-Of: odoo/enterprise#123003
Steps: - Install portal app - Go to my/addresses page. - Update main address of current user. Issues: - `Main Address` badge is not visible on main address. - Editing main address is not opening `my/account` page. Cause: - Since PR https://github.com/odoo/odoo/pull/232539 t-call syntax changed and expect to add attribute directly instead t-set but forget to adept it for `is_user_address` and `address_update_url`. Fix: - Move those variable directly into t-call instead t-set. For
Original PR description
Steps: - Install portal app - Go to my/addresses page. - Update main address of current user. Issues: - `Main Address` badge is not visible on main address. - Editing main address is not opening `my/account` page. Cause: - Since PR https://github.com/odoo/odoo/pull/232539 t-call syntax changed and expect to add attribute directly instead t-set but forget to adept it for `is_user_address` and `address_update_url`. Fix: - Move those variable directly into t-call instead t-set. Forward-Port-Of: odoo/odoo#278812
Error-1 : ``` raise ValueError('External ID not found in the system: %s' % xmlid) ValueError: External ID not found in the system: account.1_l10n_id_domestic_fiscal_position ``` Error-2 : ``` raise ValueError('External ID not found in the system: %s' % xmlid) ValueError: External ID not found in the system: account.1_tax_luxury_sales ``` Reason-1 : - In [this](https://github.com/odoo/odoo/commit/e342a45aceb60b44052c5d52e9ecc35a9a7340da) commit new account.fiscal.positions were ad
Original PR description
Error-1 : ``` raise ValueError('External ID not found in the system: %s' % xmlid) ValueError: External ID not found in the system: account.1_l10n_id_domestic_fiscal_position ``` Error-2 : ``` raise…
Error-1 :
```
raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system:
account.1_l10n_id_domestic_fiscal_position
```
Error-2 :
```
raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: account.1_tax_luxury_sales
```
Reason-1 :
- In [this](https://github.com/odoo/odoo/commit/e342a45aceb60b44052c5d52e9ecc35a9a7340da) commit new account.fiscal.positions were added and linked to acc.tax using fiscal_position_ids .
- In [this](https://github.com/odoo/odoo/blob/saas-19.2/addons/l10n_id/migrations/1.3/end-migrate_update_taxes.py) migration script, while creating taxes it didnt find fiscal positions, so need to create them first.
Reason-2 :
- original_tax_ids was also added in same commit, if client deleted those tax(ie tax_luxury_sales) will fail while creating `tax_luxury_sales_pemungut_ppn`, It needs to be created first too.
- upg : [4341887](https://upgrade.odoo.com/odoo/upgrade.request/4341887)
- opw : [6285978](https://www.odoo.com/odoo/project/70/tasks/6285978)
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#269802Currently, an error occurs when installing the hr_holidays_attendance module. **Steps to Reproduce:** - Install the `hr_attendance` module without demo data. - Go to `Attendance` > `Configuration` > `Overtime Rulesets` and open the `Default Ruleset` record. - Delete its `linked overtime rules`. - Install the `hr_holidays_attendance` module. **Error:** ```py Exception: Cannot update missing record 'hr_attendance.hr_attendance_overtime_employee_schedule_rule' odoo.tools.conver
Original PR description
Currently, an error occurs when installing the hr_holidays_attendance module. **Steps to Reproduce:** - Install the `hr_attendance` module without demo data. - Go to `Attendance` > `Configuration` >…
Currently, an error occurs when installing the hr_holidays_attendance module.
**Steps to Reproduce:**
- Install the `hr_attendance` module without demo data.
- Go to `Attendance` > `Configuration` > `Overtime Rulesets` and open the `Default Ruleset` record.
- Delete its `linked overtime rules`.
- Install the `hr_holidays_attendance` module.
**Error:**
```py
Exception: Cannot update missing record 'hr_attendance.hr_attendance_overtime_employee_schedule_rule'
odoo.tools.convert.ParseError: while parsing /home/odoo/odoo18/community/addons/hr_holidays_attendance/data/hr_holidays_attendance_data.xml:7, somewhere inside <record id="hr_attendance.hr_attendance_overtime_employee_schedule_rule" model="hr.attendance.overtime.rule">
<field name="compensable_as_leave" eval="True"/>
</record>
```
This error occurs when the user deletes all overtime rules and then installs the hr_holidays_attendance
module. During installation, the module attempts to update the deleted overtime rule records,
which raises an error [1].
This commit uses forcecreate="0" to skip updating records if the corresponding overtime
rules do not exist.
[1]- https://github.com/odoo/odoo/blob/da0a83761f38ee4a2940015b6c8f7190c310a4a0/addons/hr_holidays_attendance/data/hr_holidays_attendance_data.xml#L7-L12
sentry-7372074675
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279088
Forward-Port-Of: odoo/odoo#27765620 changes
Enhancements to existing features
If a list item has a selection blocker, the user can be stuck and forced to move to the previous or next block instead of being able to continue to edit the list item. To get around this, this commit allows selection placeholders in list items. task-6394918 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278323
Original PR description
If a list item has a selection blocker, the user can be stuck and forced to move to the previous or next block instead of being able to continue to edit the list item. To get around this, this commit allows selection placeholders in list items. task-6394918 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278323
Previously, questions in the event template could not be reordered via drag-and-drop on the Questions page. Instead of adding the handle to the inline list embedded in the event.type form view, we add it to the dedicated event.question list view (event_question_view_list). This will allow the users to reorder from the event questions and the sequence will be synced everywhere those questions appear. Steps to reproduce: 1.Go to event, configurations, and event questions. 2.We can't drag an
Original PR description
Previously, questions in the event template could not be reordered via drag-and-drop on the Questions page. Instead of adding the handle to the inline list embedded in the event.type form view, we add it to the dedicated event.question list view (event_question_view_list). This will allow the users to reorder from the event questions and the sequence will be synced everywhere those questions appear. Steps to reproduce: 1.Go to event, configurations, and event questions. 2.We can't drag and drop questions Original PR (18.0): odoo/odoo#270576 opw-6260478 Forward-Port-Of: odoo/odoo#277071
Resolved issues and error corrections
The accounting reports now handle cases where a tax that was previously configured as a group is later changed to another tax type. This prevents the Journal Report from failing and helps users continue reviewing audit reports without interruption.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
Australian payroll no longer shows an error if an employee's Tax Treatment Category is temporarily removed. The system now safely leaves the related tax treatment code empty until the required category is set again, helping payroll users continue editing employee records without interruption.
Original PR description
Currently, an error occurs when a user removes the Tax Treatment Category of an Australian employee. Steps to Reproduce: - Install the `l10n_au_hr_payroll` module with demo data. - Switch to an…
Currently, an error occurs when a user removes the Tax Treatment Category of an Australian employee. Steps to Reproduce: - Install the `l10n_au_hr_payroll` module with demo data. - Switch to an `Australian company`. - Open any `Employee` > `Payroll` > remove the `Tax Treatment Category` value. `UnboundLocalError: cannot access local variable 'code' where it is not associated with a value` After the [change] in selection field behavior, users can clear the value of the field. When the user removes the Tax Treatment Category value, the system computes the tax treatment code [1]. During this process, if no condition matches, the code variable is not initialized. Converting this uninitialized variable to a string [2] raises an error. This commit ensures that when the tax treatment category is not set, the tax treatment code is set to False with an early return. Since the tax treatment category is required field and compute the correct tax treatment code, once the category is set. [change]: https://github.com/odoo/odoo/pull/214422/changes/8d2a42ac419fdf7943a0c11beb8c5de6c6f85bef [1]- https://github.com/odoo/enterprise/blob/017743cbe97b629e9d9f1895b655014d4c3abbcb/l10n_au_hr_payroll/models/hr_version.py#L450-L451 [2]- https://github.com/odoo/enterprise/blob/017743cbe97b629e9d9f1895b655014d4c3abbcb/l10n_au_hr_payroll/models/hr_version.py#L515 No task ID Forward-Port-Of: odoo/enterprise#124067
Brazilian electronic invoices now send the required trade unit conversion factor to Avalara. This helps ensure fiscal reform tax calculations use the correct quantity basis and reduces the risk of invoice processing errors.
Original PR description
This commit adds the comexTaxUnitFactor to the json sent to Avalara when sending an invoice. comexTaxUnitFactor is a factor that convert sales quantity to comexTaxUnit, its value should be the same as cbsIbsUnitFactor. opw-6396462 Forward-Port-Of: odoo/enterprise#125695
The timesheet assistant now keeps its suggestions aligned with the date the user most recently selected, even when they navigate dates quickly. It also avoids showing project or task mapping for away-from-keyboard events, keeping those entries informational as intended.
Original PR description
Before this commit, when the user hits multiple times the arrow button to change the date displayed in timesheet assistant, the suggestions displayed could be the suggestions from another day because a rpc is made each time the user changes the date and amoung all rpcs call, the one which takes more time then the one will be taken but it is not necessary the date shown in the view. This commit uses `KeepLast` class to avoid the concurrency issue with those rpcs to be able to always take the last rpc call to get the data.
Polish JPK tax exports now use the supplier bill reference for purchase document numbers when it is available, instead of always using the internal bill number. This helps companies produce tax files that better match vendor documents and official reporting guidance.
Original PR description
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting >…
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting > Reporting > Tax Report and select `This Month`. - From the dropdown, click `JPK` > `Export XML`. - Open the generated XML file and observe the `DowodZakupu` field. **Observation:** `DowodZakupu` contains the vendor `Bill Number` even when a `Bill Reference` is set. **Root Cause:** At [1], `DowodZakupu` is populated only with the vendor `Bill number`(`move_name`) instead of using the `Bill reference`(`ref`) when available. **Fix:** This commit ensures `DowodZakupu` contains the `Bill Reference` when it is available in JPK exports. **Reference:** https://www.podatki.gov.pl/media/eqrn3dey/broszura-jpk_vat-z-deklaracj%C4%85-od-1-lutego-2026-r-en.pdf (page 41) [1]: https://github.com/odoo/enterprise/blob/4b0404058b280136f6865090562f95e18d4d7e0b/l10n_pl_reports/data/jpk_export_templates.xml#L208 opw-6299827 Forward-Port-Of: odoo/enterprise#126113 Forward-Port-Of: odoo/enterprise#121117
Payroll decimal precision settings are now protected from being reset during module upgrades. This prevents company-specific payroll rounding or rate precision choices from being silently overwritten, while still creating the default settings for new installations.
Original PR description
decimal.precision records are user-configurable settings that may be adjusted per company needs. With noupdate="0", every module upgrade resets the 'Payroll' and 'Payroll Rate' precision values back to their defaults, silently discarding any customization made by the user. This is inconsistent with the standard pattern used across Odoo modules. For example, the 'quality' module correctly loads its decimal.precision records with noupdate="1". The same convention is followed in core addons such as 'product' and 'account'. The forcecreate="True" attribute already ensures the records are created on fresh installations, so noupdate="1" only prevents overwriting existing values on upgrade — which is the expected behavior for configuration data. Forward-Port-Of: odoo/enterprise#120509
Fixed an issue where the Timesheets overtime indicator could show remaining time in hours instead of days after changing the user's language. This keeps time balances consistent and easier to understand for multilingual teams.
Original PR description
Steps to reproduce: ------------------- 1. Install Timesheets. 2. Create a new employee with a fully fixed working schedule (40h/week). 3. Open Timesheets > All Timesheets and create a new timesheet…
Steps to reproduce: ------------------- 1. Install Timesheets. 2. Create a new employee with a fully fixed working schedule (40h/week). 3. Open Timesheets > All Timesheets and create a new timesheet in the past week for this employee (e.g. 8 hours). 4. Observe the overtime indicator for the employee (it shows 32 hrs) (Click the left arrow to display it). 5. Change the timesheet encoding unit to "Days / Half-Days". 6. Return to Timesheets and observe the overtime indicator (it now correctly shows 4 days). 7. Install a language other than English (e.g. French). 8. Return to Timesheets and observe the overtime indicator again. Issue: -------- The remaining time value changes unexpectedly and displays 32 hours instead of 4 days. Cause: --------- In `get_timesheet_and_working_hours_for_employees`, the code determines whether the timesheet UoM is expressed in days by comparing the UoM name with the string `"days"`. Since UoM names are translatable, this comparison becomes invalid when the user language changes (e.g. `"jours"` in French), causing the logic to skip the day conversion and return values in hours instead. https://github.com/odoo/enterprise/blob/c48290e90fdeadf4f9ca8c44b035e601e7ed380a/timesheet_grid/models/hr_employee.py#L165-L169 Solution: ----------- Compare the timesheet UoM record with the day UoM record directly instead of relying on translated string values. see commit: https://github.com/odoo/enterprise/commit/5fbf194c5056566453a124812fd2614edfe19a82 opw-6279133 Forward-Port-Of: odoo/enterprise#126114 Forward-Port-Of: odoo/enterprise#120595
This update reverses a previous change that was only needed for an earlier version and should not have been carried forward. It helps avoid unnecessary errors when using quick create in bank reconciliation on this version.
Original PR description
This commit https://github.com/odoo/enterprise/commit/e559d9f5acbd176792db0dedc4e1f0cad7271457 fixed a problem only happening in 19.0. The commit shouldn't have been forward ported. no task id Forward-Port-Of: odoo/enterprise#126039
Accrual list reports now remember the user's chosen "As of" date when they open a report line and return using the breadcrumb. This prevents the report from unexpectedly reverting to today's date and helps users continue their review with the same reporting period and accurate grouped results.
Original PR description
Issue: In accrual list reports (Billed Not Received / Invoiced Not Delivered), selecting an "As of" date, opening a line, and returning with the breadcrumb resets the date filter to the default value…
Issue: In accrual list reports (Billed Not Received / Invoiced Not Delivered), selecting an "As of" date, opening a line, and returning with the breadcrumb resets the date filter to the default value (today's date) Steps to reproduce: 1) Open an accrual list report ( Accounting > Audit > Purchases > Bill to receive / Billed Not Received OR Invoices to be issues / invoiced Not delivered) 2) Pick any "As of" date 3) Open any row 4) Click breadcrumb to return to the accrual list 5) Observe the "As of" date has been reset to today's date To generate some data you could: create a PO, then upload the bill, validate the receipt, then you'll find it in bills received Cause: `AccrualListController.setup()` always initialized state.date with a fresh default date and did not re-put the previously saved `accrual_entry_date` from restored context https://github.com/odoo/enterprise/blob/899f0d45b2ae1dc4e5e06a2e0acb3d006d12d563/account_reports/static/src/views/accrual_list_controller.js#L10-L16 Although `setDate()` stored the selected date in context, `setup()` overwrote the UI state on controller recreation https://github.com/odoo/enterprise/blob/899f0d45b2ae1dc4e5e06a2e0acb3d006d12d563/account_reports/static/src/views/accrual_list_controller.js#L61-L65 Solution: - Persist `accrual_entry_date` in `AccrualListSearchModel` via `exportState()` / `_importState()`, so the date is restored in search context before the list model loads on breadcrumb navigation. - Initialize the date picker through `setDate()` in `onWillStart()` instead of hardcoding `DateTime.now()` in `setup()`, so restoration and user changes share the same code path. - In `setDate()`, reset grouped list caches (`currentGroups` and `groups`) before `root.load()`, because those caches are not keyed on `accrual_entry_date` and would otherwise show stale vendor groups after a date change or breadcrumb restore. opw-6232263 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#118669
Basic document users can now open the spreadsheet creation window even when they do not have access to spreadsheet templates. This removes an inconsistency that blocked them from creating blank spreadsheets from the Documents kanban view, while keeping template access restricted.
Original PR description
A basic user can access the document app and create all types of documents from the kanban view except for the spreadsheets because it requires an access to the templates. While the user cannot interact with the templates, they should have the possibility to create an empty spreadsheet. Note that it can already be done coming from the view of a spreadsheet! This revision ensures that the user can indeed access the spreadsheet creation modal even if they don't have access to the spreadsheet templates. Task-6364964 Forward-Port-Of: odoo/enterprise#126231 Forward-Port-Of: odoo/enterprise#123003
# How to reproduce - Go to a website page - Add atleast one image to the page - Go to Site > Optimize SEO - Add a description to an image - Save # The issue The description is not applied to the image. It is not present in the image's alt in the page and if we re-open the SEO modal, it is not there either. # Cause This [PR] changed the way the image's id are generated in `get_alt_image()`, but did not change the id generation in the check done in `update_alt_images()`, so this check
Original PR description
# How to reproduce - Go to a website page - Add atleast one image to the page - Go to Site > Optimize SEO - Add a description to an image - Save # The issue The description is not applied to the image. It is not present in the image's alt in the page and if we re-open the SEO modal, it is not there either. # Cause This [PR] changed the way the image's id are generated in `get_alt_image()`, but did not change the id generation in the check done in `update_alt_images()`, so this check always fails: https://github.com/odoo/odoo/blob/36eee85dbaed927ff76b2d44a44ba476e9588c72/addons/website/controllers/main.py#L894 [PR]: https://github.com/odoo/odoo/commit/1f1980a1d9835567597ca239d404f47d4677dc47 # Proposed solution Added an helper function for the id generation. This is not necessary but might prevent this from happening again, up to the reviewer to keep it or not opw-6389523 Forward-Port-Of: odoo/odoo#278675 Forward-Port-Of: odoo/odoo#277588
While preloading chart template data, if an account already exists in the db but has `active=False`, it is not found because archived records are excluded from the [`_search`]. As a result, the load attempts to create a new account. During creation, the Python constraint [`_ensure_code_is_unique`] searches with `active_test=False`, finds the archived account with the same code, and raises a ValidationError: ```py File "/home/odoo/src/odoo/saas-19.2/addons/account/models/chart_template.py"
Original PR description
While preloading chart template data, if an account already exists in the db but has `active=False`, it is not found because archived records are excluded from the [`_search`]. As a result, the load…
While preloading chart template data, if an account already exists in the db but has `active=False`, it is not found because archived records are excluded from the [`_search`].
As a result, the load attempts to create a new account. During creation, the Python constraint [`_ensure_code_is_unique`] searches with `active_test=False`, finds the archived account with the same code, and raises a ValidationError:
```py
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/chart_template.py", line 735, in _load_data
'noupdate': True,
^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 4519, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 4426, in _load_records_create
records = self.create(vals_list)
^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/decorators.py", line 363, in create
return method(self, vals_list)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_account.py", line 1057, in create
records._ensure_code_is_unique()
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/account_account.py", line 1135, in _ensure_code_is_unique
raise ValidationError(
odoo.exceptions.ValidationError: Account codes must be unique. You can't create accounts with these duplicate codes: 1.1.1.02.003, 1.1.1.02.004
```
Steps to reproduce:
- In a `v19.0` database, install `l10n_ar` with demo data.
- The accounts with codes `1.1.1.02.003` and `1.1.1.02.004` are created by [`_create_outstanding_accounts`].
- Archive those accounts and upgrade to `v19.2`.
- During the upgrade, [`_get_latam_check_outstanding_account_account`] attempts to create new accounts with the same codes, triggering the duplicate code validation.
tbg-2840
[`_search`]: https://github.com/odoo/odoo/blob/619d8ce9f31349ed06b11ead4988a4a1d9ca6bdd/addons/account/models/chart_template.py#L438
[`_ensure_code_is_unique`]: https://github.com/odoo/odoo/blob/19.0/addons/account/models/account_account.py#L1133
[`_create_outstanding_accounts`]: https://github.com/odoo/odoo/blob/06a46b083fde5688d71c5602553316c9e7160b6a/addons/account/models/chart_template.py#L925C9-L949
[`_get_latam_check_outstanding_account_account`]: https://github.com/odoo/odoo/blob/saas-19.2/addons/l10n_latam_check/models/account_chart_template.py#L60-L76
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279313
Forward-Port-Of: odoo/odoo#279092**Problem:** When creating a new task, the Customer does not follow the project the user selects: once a first project has filled it, selecting another project keeps the previous project's customer. **Steps to reproduce:** 1. Create a new task and select a project that has a customer. 2. The Customer is set to that project's customer. 3. Select another project configured with a different customer. 4. Observe the Customer keeps the first project's customer. **Current behavior:** The C
Original PR description
**Problem:** When creating a new task, the Customer does not follow the project the user selects: once a first project has filled it, selecting another project keeps the previous project's customer.…
**Problem:** When creating a new task, the Customer does not follow the project the user selects: once a first project has filled it, selecting another project keeps the previous project's customer. **Steps to reproduce:** 1. Create a new task and select a project that has a customer. 2. The Customer is set to that project's customer. 3. Select another project configured with a different customer. 4. Observe the Customer keeps the first project's customer. **Current behavior:** The Customer keeps the first selected project's customer. **Expected behavior:** The Customer follows the selected project and shows its customer. **Cause of the issue:** partner_id is filled by _compute_partner_id, which only assigns a partner while the field is empty. Once a project has filled it, selecting another project no longer refreshes the now non-empty Customer. **Fix:** Refresh the Customer from the project on project_id change, but only while the task is new (no _origin). An existing task's customer is left untouched, since it may already carry sale order lines, timesheets, materials or worksheets that must not be reset when the project changes. opw-6315902 Forward-Port-Of: odoo/odoo#278526 Forward-Port-Of: odoo/odoo#276211
**Steps to reproduce:** - Install website_forum - Create a new post on the forum with the admin - Subscribe to the post notifications using the bell button - Create a new portal user and give him 5 karma (to give him enough rights to answer and comment) - Connect with the portal user and go to the post - Create an answer - Try to comment on your own answer - AccessError is raised **Issue:** Since [1] we check comodel access (in this case `res.partner`) when adding records. Here
Original PR description
**Steps to reproduce:** - Install website_forum - Create a new post on the forum with the admin - Subscribe to the post notifications using the bell button - Create a new portal user and give him 5…
**Steps to reproduce:**
- Install website_forum
- Create a new post on the forum with the admin
- Subscribe to the post notifications using the bell button
- Create a new portal user and give him 5 karma
(to give him enough rights to answer and comment)
- Connect with the portal user and go to the post
- Create an answer
- Try to comment on your own answer
- AccessError is raised
**Issue:**
Since [1] we check comodel access (in this case `res.partner`) when adding records. Here during the `message_post` the `question_followers` are added manually as `partner_ids` before sending (the logic only relies on the original post subscribers, not on the added comment/reply).
```py
question_followers = self.env['mail.followers'].sudo().search([
('res_model', '=', self._name),
('res_id', '=', self.parent_id.id),
('partner_id', '!=', False),
]).filtered(lambda fol: comment_subtype in fol.subtype_ids).mapped('partner_id')
partner_ids += question_followers.ids
```
As the portal user has no `read` access to the subscribers the message creation fails with a traceback.
**Fix:**
Add `sudo` to the `message_post` call of `post_comment`.
[1] https://github.com/odoo/odoo/commit/aae732957c3c3b3590f5686cfccc0ab264d0b5c9
opw-5318757
Forward-Port-Of: odoo/odoo#278840
Forward-Port-Of: odoo/odoo#274751When displaying lots or serial numbers on invoices, the quantity and UoM were rendered without any separator in the SN/LN table, e.g. `1.00Units`. - Add a non-breaking space between the quantity and UoM so the table renders as `1.00 Units`. - Also align the SN/LN value cell consistently with its right-aligned column header. - Update the `sale_stock` and `sale_mrp` report tests to expect whitespace between the quantity and UoM in the rendered invoice output. Task [link](https://www.odoo.
Original PR description
When displaying lots or serial numbers on invoices, the quantity and UoM were rendered without any separator in the SN/LN table, e.g. `1.00Units`. - Add a non-breaking space between the quantity and UoM so the table renders as `1.00 Units`. - Also align the SN/LN value cell consistently with its right-aligned column header. - Update the `sale_stock` and `sale_mrp` report tests to expect whitespace between the quantity and UoM in the rendered invoice output. Task [link](https://www.odoo.com/odoo/project/967/tasks/6365178) task-6365178 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279214 Forward-Port-Of: odoo/odoo#274660
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers may be formatted or unformatted When `base_vat` is installed, VAT is stored formatted in Odoo (e.g. `CHE-530.781.296 TVA`) If the format differs, the matching fails and a new partner is created at each import ### Cause: `_retrieve_partner` lacked Swiss-specific VAT normalization logic in `_get_country_specific_vat_variants`, causing it to miss formatted variants with language suffixes (`TVA`, `MWST`, `IVA`)
Original PR description
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers may be formatted or unformatted When `base_vat` is installed, VAT is stored formatted in Odoo (e.g. `CHE-530.781.296…
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers may be formatted or unformatted When `base_vat` is installed, VAT is stored formatted in Odoo (e.g. `CHE-530.781.296 TVA`) If the format differs, the matching fails and a new partner is created at each import ### Cause: `_retrieve_partner` lacked Swiss-specific VAT normalization logic in `_get_country_specific_vat_variants`, causing it to miss formatted variants with language suffixes (`TVA`, `MWST`, `IVA`) Even when the match succeeded, `_import_ubl_create_missing_customer` still compared VAT strings without stripping `-` and lang suffixes for CH partners, causing a false mismatch and triggering partner creation anyway ### Notes: The partner match improvement is backported from 18.3: https://github.com/odoo/odoo/commit/f1a5a3d72a26ee471d2ef1d8034136208b2bcebc The original fix was incomplete — it added `_get_country_specific_vat_variants` but missed the VAT comparison fix in `_import_ubl_create_missing_customer`, allowing the issue to persist after a successful match `base_vat` is required to get the fix fully working ### Steps to reproduce: - Install `account` and `base_vat` - Create a Vendor (Name: Test CH Vendor, Country: Switzerland, Tax ID: CHE-530.781.296 TVA) - Import a [Peppol Bill](https://github.com/user-attachments/files/27202997/CH_bill_to_import.xml) with VAT `CHE530781296TVA` Before the fix, a new partner is created instead of matching the existing one opw-6353387 Forward-Port-Of: odoo/odoo#279184 Forward-Port-Of: odoo/odoo#274398
With pos_hr enabled, the cash in/out popup uses the cashier's `work_contact_id` as partner for the `account.bank.statement.line`. When that partner is archived or not part of the limited partner loading, the relation cannot be resolved in the frontend and the statement line is created with `partner_id = False`. Deleting such a cash move then crashes in `delete_cash_in_out`: File ".../point_of_sale/models/pos_session.py", line 1877, in delete_cash_in_out action = cashier_name +
Original PR description
With pos_hr enabled, the cash in/out popup uses the cashier's `work_contact_id` as partner for the `account.bank.statement.line`. When that partner is archived or not part of the limited partner…
With pos_hr enabled, the cash in/out popup uses the cashier's `work_contact_id` as partner for the `account.bank.statement.line`. When that partner is archived or not part of the limited partner loading, the relation cannot be resolved in the frontend and the statement line is created with `partner_id = False`.
Deleting such a cash move then crashes in `delete_cash_in_out`:
File ".../point_of_sale/models/pos_session.py", line 1877, in delete_cash_in_out
action = cashier_name + ': ' + str(amount)
TypeError: unsupported operand type(s) for +: 'bool' and 'str'
Steps to reproduce:
- Enable "Multi Employees per Session" (pos_hr) on a PoS config
- Archive the work contact of an employee, or make sure it is not included in the limited partner loading
- Open a session, log in as that employee and register a cash in/out
- As a manager, delete the cash move from the cash move list => Traceback, the cash move cannot be deleted
opw-6389830
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#278462
Forward-Port-Of: odoo/odoo#276598Miscellaneous changes
Optimize search_paid_order_ids to reduce ORM overhead and resolve a database bottleneck during POS synchronization. - Move currency validation from a Python post-filter into the SQL domain via config_id.currency_id. - Split the costly OR query on pos.order.line into two targeted index scans combined via UNION, dropping execution time from ~627ms to ~16ms (~40x speedup) and reducing shared read blocks from 650k+ to zero. - Align totalCount with the exact same domain and simplify state exclus
Original PR description
Optimize search_paid_order_ids to reduce ORM overhead and resolve a database bottleneck during POS synchronization. - Move currency validation from a Python post-filter into the SQL domain via config_id.currency_id. - Split the costly OR query on pos.order.line into two targeted index scans combined via UNION, dropping execution time from ~627ms to ~16ms (~40x speedup) and reducing shared read blocks from 650k+ to zero. - Align totalCount with the exact same domain and simplify state exclusions from multiple != operators to a single not in. Explain Before: https://explain.dalibo.com/plan/84095dcgfdc158a2 Explain After: https://explain.dalibo.com/plan/ag2abcdf4ge5d5e5 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278739
10 changes
Resolved issues and error corrections
The Timesheets overtime display now keeps the selected unit, such as days, even when users switch to another language. This prevents confusing differences where the same remaining time could appear as hours instead of days for translated users.
Original PR description
Steps to reproduce: ------------------- 1. Install Timesheets. 2. Create a new employee with a fully fixed working schedule (40h/week). 3. Open Timesheets > All Timesheets and create a new timesheet…
Steps to reproduce: ------------------- 1. Install Timesheets. 2. Create a new employee with a fully fixed working schedule (40h/week). 3. Open Timesheets > All Timesheets and create a new timesheet in the past week for this employee (e.g. 8 hours). 4. Observe the overtime indicator for the employee (it shows 32 hrs) (Click the left arrow to display it). 5. Change the timesheet encoding unit to "Days / Half-Days". 6. Return to Timesheets and observe the overtime indicator (it now correctly shows 4 days). 7. Install a language other than English (e.g. French). 8. Return to Timesheets and observe the overtime indicator again. Issue: -------- The remaining time value changes unexpectedly and displays 32 hours instead of 4 days. Cause: --------- In `get_timesheet_and_working_hours_for_employees`, the code determines whether the timesheet UoM is expressed in days by comparing the UoM name with the string `"days"`. Since UoM names are translatable, this comparison becomes invalid when the user language changes (e.g. `"jours"` in French), causing the logic to skip the day conversion and return values in hours instead. https://github.com/odoo/enterprise/blob/c48290e90fdeadf4f9ca8c44b035e601e7ed380a/timesheet_grid/models/hr_employee.py#L165-L169 Solution: ----------- Compare the timesheet UoM record with the day UoM record directly instead of relying on translated string values. see commit: https://github.com/odoo/enterprise/commit/5fbf194c5056566453a124812fd2614edfe19a82 opw-6279133 Forward-Port-Of: odoo/enterprise#126114 Forward-Port-Of: odoo/enterprise#120595
Polish JPK tax exports now use the vendor bill reference in the purchase document field when one is provided. This helps exported tax files match supplier documentation and supports compliance with Polish reporting expectations.
Original PR description
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting >…
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting > Reporting > Tax Report and select `This Month`. - From the dropdown, click `JPK` > `Export XML`. - Open the generated XML file and observe the `DowodZakupu` field. **Observation:** `DowodZakupu` contains the vendor `Bill Number` even when a `Bill Reference` is set. **Root Cause:** At [1], `DowodZakupu` is populated only with the vendor `Bill number`(`move_name`) instead of using the `Bill reference`(`ref`) when available. **Fix:** This commit ensures `DowodZakupu` contains the `Bill Reference` when it is available in JPK exports. **Reference:** https://www.podatki.gov.pl/media/eqrn3dey/broszura-jpk_vat-z-deklaracj%C4%85-od-1-lutego-2026-r-en.pdf (page 41) [1]: https://github.com/odoo/enterprise/blob/4b0404058b280136f6865090562f95e18d4d7e0b/l10n_pl_reports/data/jpk_export_templates.xml#L208 opw-6299827 Forward-Port-Of: odoo/enterprise#126113 Forward-Port-Of: odoo/enterprise#121117
This fix prevents the Journal Report from crashing when an invoice contains a tax that was originally a group of taxes but was later changed to a percentage tax. Accounting users can now open the audit report reliably even after tax configuration changes.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
This change removes an incorrect update that was carried forward from an older version where it was no longer needed. It prevents an error in the bank reconciliation quick create flow, helping accountants continue their work without interruption.
Original PR description
This commit https://github.com/odoo/enterprise/commit/e559d9f5acbd176792db0dedc4e1f0cad7271457 fixed a problem only happening in 19.0. The commit shouldn't have been forward ported. no task id
Payroll decimal precision settings will no longer be reset to default values when the payroll module is upgraded. This protects company-specific payroll configuration and avoids unexpected changes after maintenance updates.
Original PR description
decimal.precision records are user-configurable settings that may be adjusted per company needs. With noupdate="0", every module upgrade resets the 'Payroll' and 'Payroll Rate' precision values back to their defaults, silently discarding any customization made by the user. This is inconsistent with the standard pattern used across Odoo modules. For example, the 'quality' module correctly loads its decimal.precision records with noupdate="1". The same convention is followed in core addons such as 'product' and 'account'. The forcecreate="True" attribute already ensures the records are created on fresh installations, so noupdate="1" only prevents overwriting existing values on upgrade — which is the expected behavior for configuration data. Forward-Port-Of: odoo/enterprise#120509
This fix ensures the Swedish point-of-sale test consistently completes order creation before finishing. It reduces random test failures, helping maintain confidence in the Swedish POS localization without changing business workflows.
Original PR description
## Issue The tour `test_l10n_se_pos_01` does not consistently create its `pos_order`. This leads to the following assert failing:…
## Issue The tour `test_l10n_se_pos_01` does not consistently create its `pos_order`. This leads to the following assert failing: https://github.com/odoo/enterprise/blob/0f6f6fac892bc8cec477160a790d52fbf053be99/l10n_se_pos/tests/test_se_pos.py#L40-L42 ## Steps to reproduce 1. Install `l10n_se_pos` 2. Run the test `test_l10n_se_pos_01` 3. **The test fails non-deterministically** ## Fix We use `clickNextOrder()` at the end of the tour to ensure the creation of the order, like other tests already do (e.g., [FinishResidualOrder](https://github.com/odoo/odoo/blob/7fc645e5a3fad9255432e7cc68d47bd0971d3d77/addons/pos_restaurant/static/tests/tours/pos_restaurant_tour.js#L676-L677), [test_name_preset_skip_screen](https://github.com/odoo/odoo/blob/7fc645e5a3fad9255432e7cc68d47bd0971d3d77/addons/pos_restaurant/static/tests/tours/pos_restaurant_tour.js#L1333-L1334), [PosOrderCreationTourPdis](https://github.com/odoo/enterprise/blob/08d5172a8c3310af0c51e18a281c544f83f5aed7/pos_enterprise/static/tests/tours/point_of_sale/pos_tour.js#L141-L142), ...). runbot-238568
Basic users can now open the spreadsheet creation window from Documents even when they cannot access spreadsheet templates. This removes an unnecessary blocker and lets them create blank spreadsheets consistently from the document view.
Original PR description
A basic user can access the document app and create all types of documents from the kanban view except for the spreadsheets because it requires an access to the templates. While the user cannot interact with the templates, they should have the possibility to create an empty spreadsheet. Note that it can already be done coming from the view of a spreadsheet! This revision ensures that the user can indeed access the spreadsheet creation modal even if they don't have access to the spreadsheet templates. Task-6364964 Forward-Port-Of: odoo/enterprise#126231 Forward-Port-Of: odoo/enterprise#123003
The AutoComplete component wraps a text input that already renders its own suggestion dropdown, so the browser's native suggestions must stay out of the way. In 12/2024 in this commit [1] the input's autocomplete was switched from `off` to `new-password` on the premise that `off` is not respected by browsers. In 02/2025, in this commit [2] then made it the component default so many2x pickers stay clean. Chrome runs two independent suggestion mechanisms, and each attribute silences only
Original PR description
The AutoComplete component wraps a text input that already renders its own suggestion dropdown, so the browser's native suggestions must stay out of the way. In 12/2024 in this commit [1] the input's…
The AutoComplete component wraps a text input that already renders its own suggestion dropdown, so the browser's native suggestions must stay out of the way. In 12/2024 in this commit [1] the input's autocomplete was switched from `off` to `new-password` on the premise that `off` is not respected by browsers. In 02/2025, in this commit [2] then made it the component default so many2x pickers stay clean. Chrome runs two independent suggestion mechanisms, and each attribute silences only one of them: - `off` is ignored when the input has a name and Chrome holds autofill (address) data for it. - `new-password` is ignored when Chrome offers "frequently used values", i.e. the form-history dropdown. [3] So `new-password` does not always work. It only stays hidden while the field is ineligible for those suggestions. A field becomes eligible as soon as it gains an `id` and an associated `<label>`. On `saas-19.3` this is provable on commit [4] where adding a prefix icon gave the link popover URL input an `id` + `<label for>`, and the native dropdown resurfaced over the custom URL/page suggestions. This branch targets `saas-18.4`, where the regression is NOT reproducible because that URL input has no `id`/`label` yet. The fix is applied here anyway to avoid the gap that any later `label`/`id` addition re-exposes (as commit [4] proved), and the fix can be forward ported to `saas-19.3`. The website editor's URL field implements autocomplete without the `AutoComplete` component, so the default does not reach it. so `autocomplete="off"` is set directly on that input. [1]: https://github.com/odoo/odoo/commit/9c0f5612 [2]: https://github.com/odoo/odoo/commit/2980694b (opw-4551051) [3]: https://issues.chromium.org/issues/41163264#comment30 [4]: https://github.com/odoo/odoo/commit/2b4d04d1 (task-6034288) task-6370552 Forward-Port-Of: odoo/odoo#279203 Forward-Port-Of: odoo/odoo#277501
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers may be formatted or unformatted When `base_vat` is installed, VAT is stored formatted in Odoo (e.g. `CHE-530.781.296 TVA`) If the format differs, the matching fails and a new partner is created at each import ### Cause: `_retrieve_partner` lacked Swiss-specific VAT normalization logic in `_get_country_specific_vat_variants`, causing it to miss formatted variants with language suffixes (`TVA`, `MWST`, `IVA`)
Original PR description
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers may be formatted or unformatted When `base_vat` is installed, VAT is stored formatted in Odoo (e.g. `CHE-530.781.296…
### Issue: When importing EDI documents such as Peppol files, Swiss VAT numbers may be formatted or unformatted When `base_vat` is installed, VAT is stored formatted in Odoo (e.g. `CHE-530.781.296 TVA`) If the format differs, the matching fails and a new partner is created at each import ### Cause: `_retrieve_partner` lacked Swiss-specific VAT normalization logic in `_get_country_specific_vat_variants`, causing it to miss formatted variants with language suffixes (`TVA`, `MWST`, `IVA`) Even when the match succeeded, `_import_ubl_create_missing_customer` still compared VAT strings without stripping `-` and lang suffixes for CH partners, causing a false mismatch and triggering partner creation anyway ### Notes: The partner match improvement is backported from 18.3: https://github.com/odoo/odoo/commit/f1a5a3d72a26ee471d2ef1d8034136208b2bcebc The original fix was incomplete — it added `_get_country_specific_vat_variants` but missed the VAT comparison fix in `_import_ubl_create_missing_customer`, allowing the issue to persist after a successful match `base_vat` is required to get the fix fully working ### Steps to reproduce: - Install `account` and `base_vat` - Create a Vendor (Name: Test CH Vendor, Country: Switzerland, Tax ID: CHE-530.781.296 TVA) - Import a [Peppol Bill](https://github.com/user-attachments/files/27202997/CH_bill_to_import.xml) with VAT `CHE530781296TVA` Before the fix, a new partner is created instead of matching the existing one opw-6353387 Forward-Port-Of: odoo/odoo#279184 Forward-Port-Of: odoo/odoo#274398
Miscellaneous changes
Optimize search_paid_order_ids to reduce ORM overhead and resolve a database bottleneck during POS synchronization. - Move currency validation from a Python post-filter into the SQL domain via config_id.currency_id. - Split the costly OR query on pos.order.line into two targeted index scans combined via UNION, dropping execution time from ~627ms to ~16ms (~40x speedup) and reducing shared read blocks from 650k+ to zero. - Align totalCount with the exact same domain and simplify state exclus
Original PR description
Optimize search_paid_order_ids to reduce ORM overhead and resolve a database bottleneck during POS synchronization. - Move currency validation from a Python post-filter into the SQL domain via config_id.currency_id. - Split the costly OR query on pos.order.line into two targeted index scans combined via UNION, dropping execution time from ~627ms to ~16ms (~40x speedup) and reducing shared read blocks from 650k+ to zero. - Align totalCount with the exact same domain and simplify state exclusions from multiple != operators to a single not in. Explain Before: https://explain.dalibo.com/plan/84095dcgfdc158a2 Explain After: https://explain.dalibo.com/plan/ag2abcdf4ge5d5e5 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278739
5 changes
Resolved issues and error corrections
Users can now click custom fields in the Documents list view and edit them directly, just like standard fields. This removes an extra step and makes customized document workflows easier to use.
Original PR description
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The…
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The user has to first click a standard editable field (like "Owner") to put the row into edit mode before they can modify the custom field. This occurs because we use a hardcoded whitelist (`editableColumns`) of standard fields allowed to trigger edit mode. Custom fields (`x_`) are missing from this static list. This commit resolves the issue by dynamically injecting visible, non-readonly custom fields into the `editableColumns` whitelist. This allows user-created fields to be edited inline as expected. **Steps to reproduce:** - Documents > Studio > List view > Add any field that accepts user input (e.g. Text/char) > save/exit - In the same Documents list view > select a row > click the cell belonging to the newly created field > observe that the row does not enter edit mode - In the same Documents list view > select a row > click a standard editable cell, then click the cell belonging to our newly created field > observe that this then allows us to edit our field **Current behavior before PR:** - Custom fields do not trigger inline edit mode **Desired behavior after PR is merged:** - Custom fields trigger inline edit mode opw-6378102 Forward-Port-Of: odoo/enterprise#125239
The Accounting Reports module now handles invoices that used a grouped tax before that tax was later changed to a percentage tax. This prevents the Journal Report from crashing and lets users continue reviewing audit reports normally.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
The POS preparation display badge now counts the same active orders shown on the preparation screen, including orders kept open overnight. Orders removed by a reset are no longer counted, reducing confusion for staff monitoring kitchen or preparation workloads.
Original PR description
Steps to reproduce: - Configure a preparation display on a POS config with a product category - Place an order and leave it in a non-final stage - Keep the session open past midnight Issue: The…
Steps to reproduce: - Configure a preparation display on a POS config with a product category - Place an order and leave it in a non-final stage - Keep the session open past midnight Issue: The kanban order-count badge drops the order once its create_date falls behind "today", while the preparation screen still lists it. The same divergence makes the badge keep counting an order that a "Reset" already removed from the screen. _compute_order_count() scoped its search on pos_config_id and create_date >= today, whereas the screen is built by get_preparation_display_order() from _get_open_orders_in_display() and _get_stageless_orders_in_display(), which have no date filter and instead bound the set by the order stage `done` flag and the session state. An order open across midnight is therefore in the screen set but not in the badge set. Conversely reset() marks the current stage done, which drops the order from the screen set, but the badge only skipped orders whose latest stage is the final stage, so an order reset while still in the first stage stayed counted. opw-6414302 Forward-Port-Of: odoo/enterprise#126139 Forward-Port-Of: odoo/enterprise#125984
Basic users can now open the spreadsheet creation window from Documents even when they do not have access to spreadsheet templates. This removes an unnecessary blocker and lets them create empty spreadsheets consistently from the Documents app.
Original PR description
A basic user can access the document app and create all types of documents from the kanban view except for the spreadsheets because it requires an access to the templates. While the user cannot interact with the templates, they should have the possibility to create an empty spreadsheet. Note that it can already be done coming from the view of a spreadsheet! This revision ensures that the user can indeed access the spreadsheet creation modal even if they don't have access to the spreadsheet templates. Task-6364964 Forward-Port-Of: odoo/enterprise#126231 Forward-Port-Of: odoo/enterprise#123003
Appointment cancellation emails are now sent in the language of the customer who booked the appointment, matching the behavior of confirmation emails. This avoids confusion for customers who previously received cancellations in the staff member’s language instead of their own.
Original PR description
**Problem:** When an appointment is cancelled, the cancellation email is always sent in the organizer's (staff member's) language, ignoring the booking customer's language. The booking confirmation,…
**Problem:**
When an appointment is cancelled, the cancellation email is always sent in the organizer's (staff member's) language, ignoring the booking customer's language. The booking confirmation, by contrast, is correctly localized.
**Steps to reproduce:**
1. Set a contact's language to a non-default one (e.g. Romanian).
2. Book an appointment for that contact (they are the booker/attendee).
3. Cancel the appointment.
4. The customer received the confirmation in Romanian but the cancellation email arrives in English.
**Current behavior:**
The cancellation email is rendered in the organizer's language.
**Expected behavior:**
The cancellation email is rendered in the booking customer's language, like the confirmation/invitation email.
**Cause of the issue:**
The cancellation uses `appointment_canceled_mail_template`, whose `lang` is `{{ object.partner_id.lang }}`. On `calendar.event`, `partner_id` is `related='user_id.partner_id'`, i.e. the organizer, not the customer. The template is posted once per event (via `_track_template`), so its single rendering language applies to every recipient, including attendees whose own language differs. The confirmation email is unaffected because it is the per-attendee `attendee_invitation_mail_template` (model `calendar.attendee`), rendered once per attendee in that attendee's language.
**Fix:**
Deriving the language from `appointment_booker_id` makes the cancellation consistent with the other appointment mails, which are meant for the person who booked the meeting. It falls back to `partner_id` when there is no booker (e.g. an event not created through the appointment flow), preserving the previous behavior in that case.
opw-6323179
Forward-Port-Of: odoo/enterprise#1241165 changes
Resolved issues and error corrections
Users can now click custom fields in the Documents list view and edit them directly, without first activating another standard field. This makes Studio-added fields behave consistently with built-in fields and reduces friction when updating document metadata.
Original PR description
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The…
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The user has to first click a standard editable field (like "Owner") to put the row into edit mode before they can modify the custom field. This occurs because we use a hardcoded whitelist (`editableColumns`) of standard fields allowed to trigger edit mode. Custom fields (`x_`) are missing from this static list. This commit resolves the issue by dynamically injecting visible, non-readonly custom fields into the `editableColumns` whitelist. This allows user-created fields to be edited inline as expected. **Steps to reproduce:** - Documents > Studio > List view > Add any field that accepts user input (e.g. Text/char) > save/exit - In the same Documents list view > select a row > click the cell belonging to the newly created field > observe that the row does not enter edit mode - In the same Documents list view > select a row > click a standard editable cell, then click the cell belonging to our newly created field > observe that this then allows us to edit our field **Current behavior before PR:** - Custom fields do not trigger inline edit mode **Desired behavior after PR is merged:** - Custom fields trigger inline edit mode opw-6378102 Forward-Port-Of: odoo/enterprise#125239
The accounting reports now handle cases where a tax was originally part of a tax group but later changed, avoiding a crash when opening the Journal Report. This helps users access audit reporting reliably even after tax configuration changes.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
Quotations created from helpdesk repair orders now correctly use the salesperson assigned to the customer. This prevents sales ownership from being left blank, helping teams route follow-up and reporting correctly.
Original PR description
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to…
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to Reproduce:** - Install `helpdesk_repair`. - Go to `Helpdesk` > `Configuration` > `Helpdesk Teams`. - Open a team recod and enable `Repairs`. - Create a `contact/customer` with a `salesperson` assigned. - Go to `Helpdesk`, create a ticket for that `customer`, and select the `helpdesk team` configured above. - Click `Repair`, then click `Create Quotation`. - Open the quotation and check the `Salesperson` field in the `Other Info` tab. **Current behavior:** The Salesperson field on the quotation remains empty. **Expected behavior:** The Salesperson field on the quotation should inherit the salesperson assigned to the selected customer/contact. **Cause of the issue:** When a repair order is created from a helpdesk ticket, default_user_id [1] is passed in the context . This value is propagated when creating the repair order [2] . Later, when creating the quotation from the repair order [3], the same context is reused. Because default_user_id is already present in the context, it overrides the precomputation of user_id from the customer. As a result, user_id is initialized with an empty value and remains unset. **Fix:** This commit ensures that default_user_id is removed from the context before creating the sale order. Without a default value for user_id, the field is correctly precomputed from the selected customer, and the salesperson is properly assigned. [1]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L52 [2]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L36-L40 [3]: https://github.com/odoo/odoo/blob/29328b8fccff833c14de317b51f3b4e5a8c40f75/addons/repair/models/repair.py#L357 opw-6344939 Forward-Port-Of: odoo/enterprise#122980
Appointment cancellation emails are now sent in the language of the person who booked the appointment, matching confirmation emails. This avoids confusing customers with cancellation notices in the staff member’s language, while keeping the old behavior for non-appointment events.
Original PR description
**Problem:** When an appointment is cancelled, the cancellation email is always sent in the organizer's (staff member's) language, ignoring the booking customer's language. The booking confirmation,…
**Problem:**
When an appointment is cancelled, the cancellation email is always sent in the organizer's (staff member's) language, ignoring the booking customer's language. The booking confirmation, by contrast, is correctly localized.
**Steps to reproduce:**
1. Set a contact's language to a non-default one (e.g. Romanian).
2. Book an appointment for that contact (they are the booker/attendee).
3. Cancel the appointment.
4. The customer received the confirmation in Romanian but the cancellation email arrives in English.
**Current behavior:**
The cancellation email is rendered in the organizer's language.
**Expected behavior:**
The cancellation email is rendered in the booking customer's language, like the confirmation/invitation email.
**Cause of the issue:**
The cancellation uses `appointment_canceled_mail_template`, whose `lang` is `{{ object.partner_id.lang }}`. On `calendar.event`, `partner_id` is `related='user_id.partner_id'`, i.e. the organizer, not the customer. The template is posted once per event (via `_track_template`), so its single rendering language applies to every recipient, including attendees whose own language differs. The confirmation email is unaffected because it is the per-attendee `attendee_invitation_mail_template` (model `calendar.attendee`), rendered once per attendee in that attendee's language.
**Fix:**
Deriving the language from `appointment_booker_id` makes the cancellation consistent with the other appointment mails, which are meant for the person who booked the meeting. It falls back to `partner_id` when there is no booker (e.g. an event not created through the appointment flow), preserving the previous behavior in that case.
opw-6323179
Forward-Port-Of: odoo/enterprise#124116Steps to reproduce: Use the real testing credentials Create a SEZ partner Create an invoice and ewaybill Select the type of Ewaybill as Export Tax Invoice We get error code-450 which clearly states, `450 For outward-export ewaybill, To GSTIN has to be either URP or SEZ` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
Steps to reproduce: Use the real testing credentials Create a SEZ partner Create an invoice and ewaybill Select the type of Ewaybill as Export Tax Invoice We get error code-450 which clearly states, `450 For outward-export ewaybill, To GSTIN has to be either URP or SEZ` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
21 changes
Enhancements to existing features
The French localization reporting screens have been updated to work with the latest interface framework used by Odoo. This keeps fiscal declaration and reporting features maintainable and aligned with platform upgrades, with little expected change for end users.
Original PR description
Update the code of l10n_fr_{pdp,reports} to follow the new Owl 3.
task-6353237
Linked:https://github.com/odoo/odoo/pull/278004Resolved issues and error corrections
When the same delivery order is processed from two open POS sessions at the same time, the system now shows a proper user-facing warning instead of a technical error. This helps staff understand that the order was already printed and avoids confusing error messages during automated Urban Piper order handling.
Original PR description
`* = pos_platform_order, pos_urban_piper` ## Steps to Reproduce: - Install POS Restaurant. - Configure Urban Piper. - Enable "Auto Acknowledge Orders" for a platform(e.g; Zomato) to automatically print delivery orders. - Configure a printer for the POS shop. - Open the same POS session in two different browsers. - Place a test order from Atlas (UrbanPiper). ## Error: `ValueError - This delivery order has already been printed automatically.` ## Cause: When the same delivery order is processed concurrently for both sessions, the backend raises an error when it attempts to print the order again. ## Fix: Replace ValueError with UserError and mark the error message as translatable. sentry-7609743093 Forward-Port-Of: odoo/enterprise#124304
Invoices using Brazil's fiscal reform flow now include the required commercial export tax unit conversion factor when sent to Avalara. This helps ensure tax calculations and reporting use the expected quantity conversion data, reducing the risk of invoice processing errors.
Original PR description
This commit adds the comexTaxUnitFactor to the json sent to Avalara when sending an invoice. comexTaxUnitFactor is a factor that convert sales quantity to comexTaxUnit, its value should be the same as cbsIbsUnitFactor. opw-6396462 Forward-Port-Of: odoo/enterprise#125695
The Payroll dashboard no longer crashes when a payroll structure type has no scheduled pay configured. A safe fallback keeps the dashboard available, helping payroll teams avoid disruption from incomplete configuration.
Original PR description
If one of the Payroll Structure Types has the Scheduled Pay field unset, opening the Payroll dashboard raises a traceback. Steps to reproduce the error: - Install ``hr_payroll`` module - Go to…
If one of the Payroll Structure Types has the Scheduled Pay field unset, opening the Payroll dashboard raises a traceback. Steps to reproduce the error: - Install ``hr_payroll`` module - Go to Payroll > Configuration > Settings > Set Payroll Closing Date > Save - Go to Payroll > Configuration > Structure Types > Create a new Structure Type > Unset Scheduled Pay - Open Dashboard Traceback: ```py AttributeError: 'bool' object has no attribute 'title' ``` https://github.com/odoo/enterprise/blob/9a3ea83a432f42f62076a50fca6bc771a2de96bf/hr_payroll/models/hr_payroll_warning.py#L413-L419 The dashboard collects the scheduled pay values from all structure types and later calls ``schedule.title()`` to build the labels. When a Structure Type has no Scheduled Pay configured, so ``schedule`` becomes ``False``, leading to the traceback. ``_get_schedule_pay`` method can return False at [1], So, It will generate the traceback from below line also. https://github.com/odoo/enterprise/blob/8a3d87d51a9a3c4df656a328a9179ee43541022d/hr_payroll/models/hr_payroll_warning.py#L401 Solution: Added a fallback value when default scheduled pay is False. [1]: https://github.com/odoo/enterprise/blob/8a3d87d51a9a3c4df656a328a9179ee43541022d/hr_payroll/models/hr_payroll_warning.py#L149-L154 sentry-7583037488 Forward-Port-Of: odoo/enterprise#126127 Forward-Port-Of: odoo/enterprise#122492
Restaurant appointment views no longer crash when a table has no linked resource. This helps staff keep using the schedule reliably even when some table setup details are missing.
Original PR description
When a table doesn't have a resource, the appointment_resource_id is undefined and the gantt renderer was crashing when trying to access its id. This commit adds a check to ensure that the appointment_resource_id exists before trying to access its id. Forward-Port-Of: odoo/enterprise#125331
This fixes an automated test for Mexican point of sale invoicing by ensuring an order is fully synchronized before a refund is started. It helps keep validation of the refund workflow stable and reduces false test failures, without changing day-to-day user functionality.
Original PR description
In this commit: =============== - Fix the `test_mx_pos_invoice_order_and_refund` tour, which fails with the warning: `The amount of the order must be positive for a sale and negative for a refund`. - The failure is caused by the refund flow starting before the original order has been fully synced with the backend. - A previous attempt to fix this in odoo/enterprise#109362 by waiting for `FeedbackScreen.isShown()` was not sufficient. Fix: ==== - Add a `Chrome.waitForOrdersSync()` waiting step to the tour to ensure the original order is fully synced before starting the refund flow. Error: 237980 Forward-Port-Of: odoo/enterprise#124948
New contacts assigned a Partner Level now automatically receive a barcode when they are saved. This ensures front desk partnership processes have the needed barcode immediately, avoiding manual fixes or missing access details.
Original PR description
Steps to reproduce: - Go to Contacts. - Create a new contact and assign a Partner Level before saving. - Save the record. Current behavior: - When creating a new contact with a Partner Level, the barcode is not generated automatically. Solution: - Add barcode generation logic to the create() method so that a barcode is automatically generated when a new contact is created with a Partner Level. TaskId-6236375 Forward-Port-Of: odoo/enterprise#125967
Users can now create Google Booking merchant records without errors when the website app is not installed. The change prevents the system from relying on a website-specific field unless it is available, improving reliability for appointment setup.
Original PR description
Currently, an error occurs when a user creates a Google Reserve Merchant record. **Steps to Reproduce:** - Install the `appointment_google_reserve` module. - Go to `Appointments` > `Configuration` >…
Currently, an error occurs when a user creates a Google Reserve Merchant record. **Steps to Reproduce:** - Install the `appointment_google_reserve` module. - Go to `Appointments` > `Configuration` > `Google Booking`. - Click `New` to create a record. `AttributeError: 'website' object has no attribute 'homepage_url'` After this [recent commit], as part of the context-based website resolution refactoring, the `default_website` record is now available even without the `website` module because it is created in `base` [1]. When a user creates a Google Reserve Merchant record, it attempts to set the default URL using the default website from `base`. However, it then tries to access the `homepage_url` field, which is defined in the `website` module [2]. Since the `website` module is not installed, this raises the error [3]. This commit ensures that before accessing `homepage_url`, it first checks whether the `homepage_url` field exists when creating the merchant record, since this field depends on the `website` module. [recent commit]: https://github.com/odoo/odoo/commit/ae81b6f6074632d1a609387e53f97a61ee6c95f4 [1]: https://github.com/odoo/odoo/blob/ea0e2750a43e337bc6d9a00489a30df3fc0616c7/odoo/addons/base/data/website.xml#L5-L9 [2]: https://github.com/odoo/odoo/blob/ea0e2750a43e337bc6d9a00489a30df3fc0616c7/addons/website/models/website.py#L168 [3]- https://github.com/odoo/enterprise/blob/01b0cf4e2f2e2c63c02c3429d029c90639de1322/appointment_google_reserve/models/google_reserve_merchant.py#L21-L22 Task-6395376 sentry-7630852653 Forward-Port-Of: odoo/enterprise#125680
The Accounting reports now handle cases where a grouped tax used on past journal items has later been changed to a regular tax. This prevents the Journal Report from failing and helps users continue reviewing audit data without interruption.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
This fix ensures German POS fiscal transaction cancellations can proceed even when the original active transaction has missing receipt details. It prevents rejection by the fiscal service while keeping existing transaction data unchanged when available.
Original PR description
When cancelling active transactions, the schema was forwarded as-is from the listed transaction. ACTIVE transactions can have an empty schema, and Fiskaly rejects the cancellation PUT with:
{
"code": "E_TX_NO_TYPE_DEFINED",
"message": "`schema.raw.process_type` must be defined for
updating or finishing a transaction",
"status_code": 409,
"error": "Conflict"
}
Fall back to a minimal CANCELLATION receipt schema when the transaction has no schema, while preserving any schema that is already present.
opw-6345005
Forward-Port-Of: odoo/enterprise#122130The AI icon now appears consistently in areas such as Knowledge, Discuss, Website SEO, and Social posting. This fixes a visual issue where the icon could be missing or incorrectly treated as a custom icon, improving clarity for users interacting with AI features.
Original PR description
__Before commit__ Following odoo/enterprise@866597419, the AI icon was not showing in the Knowledge WysiwygArticleHelper because the icon was set in the CSS on the `.oi-ai-logo` elements. __After commit__ The AI icon is now set everywhere using `data-icon="oi-ai-logo"`. <img width="1129" height="530" alt="image" src="https://github.com/user-attachments/assets/572e4d3b-2926-40e8-bfd2-cd6d1aa47e11" /> task-6377407
Payroll decimal precision settings will no longer be reset to default values when the module is upgraded. This protects company-specific payroll configuration and prevents silent loss of user adjustments.
Original PR description
decimal.precision records are user-configurable settings that may be adjusted per company needs. With noupdate="0", every module upgrade resets the 'Payroll' and 'Payroll Rate' precision values back to their defaults, silently discarding any customization made by the user. This is inconsistent with the standard pattern used across Odoo modules. For example, the 'quality' module correctly loads its decimal.precision records with noupdate="1". The same convention is followed in core addons such as 'product' and 'account'. The forcecreate="True" attribute already ensures the records are created on fresh installations, so noupdate="1" only prevents overwriting existing values on upgrade — which is the expected behavior for configuration data. Forward-Port-Of: odoo/enterprise#120509
This fix makes status labels in payroll-related dropdown badges readable again, such as states shown on employee forms. It helps users quickly understand record statuses without confusion or visual obstruction.
Original PR description
Users are unable to read the text labels for record states (such as employee form state). This fixes the problem. task-6432088
This fixes a false collaboration error that could appear while automated Knowledge tours were running, even though collaboration was not involved. The change helps keep test results reliable and reduces noise in build validation.
Original PR description
This aims to fix Runbot build error #937788 ([1]) which wasn't fully fixed by commit [2] (see error #944595 ([3])). A collaboration error was thrown during a tour which makes no use of collaboration. Commit [2] made sure the bus from the previous test didn't persist when running this tour so it doesn't interfere, but it didn't fully reset it. [1]: https://runbot.odoo.com/odoo/runbot.build.error/937788 [2]: https://github.com/odoo/enterprise/commit/a6050dd60c587d09443907bdf955805159dbdb2e [3]: https://runbot.odoo.com/odoo/runbot.build.error/944595 Forward-Port-Of: odoo/enterprise#126195
Studio report editing now preserves an empty paragraph when a user deletes its last character. This prevents accidental layout changes and makes report editing behave more predictably, matching the website builder experience.
Original PR description
Problem: In Studio reports, deleting the last character of a paragraph removes the entire paragraph. Cause: `cleanEmptyStructuralContainers` removes the empty paragraph because it is considered empty. Solution: Disable `cleanEmptyStructuralContainers` for reports same as website builder. Steps to reproduce: - Create a new report. - Add multiple paragraphs. - Leave one paragraph with a single character. - Delete the character. - Observe that the paragraph is removed. task-6368965 Forward-Port-Of: odoo/enterprise#126200 Forward-Port-Of: odoo/enterprise#124834
Polish JPK tax exports now use the vendor bill reference in the purchase document field when that reference is available. This helps exported tax files match official guidance and reduces the risk of mismatched purchase documentation during reporting.
Original PR description
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting >…
**Steps to reproduce:** - Install the `l10n_pl_reports` module and switch to a `PL Company`. - Create and confirm a vendor bill with a `Bill Reference` and `Taxes`. - Navigate to Accounting > Reporting > Tax Report and select `This Month`. - From the dropdown, click `JPK` > `Export XML`. - Open the generated XML file and observe the `DowodZakupu` field. **Observation:** `DowodZakupu` contains the vendor `Bill Number` even when a `Bill Reference` is set. **Root Cause:** At [1], `DowodZakupu` is populated only with the vendor `Bill number`(`move_name`) instead of using the `Bill reference`(`ref`) when available. **Fix:** This commit ensures `DowodZakupu` contains the `Bill Reference` when it is available in JPK exports. **Reference:** https://www.podatki.gov.pl/media/eqrn3dey/broszura-jpk_vat-z-deklaracj%C4%85-od-1-lutego-2026-r-en.pdf (page 41) [1]: https://github.com/odoo/enterprise/blob/4b0404058b280136f6865090562f95e18d4d7e0b/l10n_pl_reports/data/jpk_export_templates.xml#L208 opw-6299827 Forward-Port-Of: odoo/enterprise#126113 Forward-Port-Of: odoo/enterprise#121117
This update fixes several visual issues where AI and call-related icons could appear misaligned, incorrectly sized, or fail to show in parts of Odoo. Users should see a more consistent interface across AI, Knowledge, Social, Website, Discuss, and VoIP features.
Original PR description
task-6377407
Code cleanup and technical improvements
This update keeps IoT-related screens and controls aligned with a renamed internal interface in the underlying web framework. It is a technical cleanup that helps maintain compatibility and should not change day-to-day user workflows.
Original PR description
In this commit: - The Owl props API has been renamed to useProps. - Updates the affected IoT-related modules accordingly by renaming imports and replacing `props(...)` with `useProps(...)`. Task:6403054 Community PR : https://github.com/odoo/odoo/pull/278327
This update cleans up AI Website code to match project quality standards without changing business functionality. It helps keep the website-building tools easier to maintain and reduces the risk of small code-quality issues affecting future changes.
This update modernizes parts of online bank synchronization and online payment screens to align with the latest Odoo web framework. It is mainly an internal technical refresh, helping keep banking features reliable and maintainable without introducing notable business workflow changes.
Original PR description
- Replace useService("orm") with usePlugin(ORM)
- Convert account_duplicate_transaction_service into
account_duplicate_transaction_plugin; rename
useCheckDuplicateService -> useCheckDuplicatePlugin
- Replace `static props = {...}` with `props = useProps(...)`
- fetch_missing_transactions_cog_menu uses `orm.unscoped.call` instead
of `orm.call` to keep the RPC alive after component
destruction.
task-6350965This update aligns several enterprise app components with a broader internal restructuring of the communication framework. It should not change day-to-day behavior for users, but it helps keep Approvals, Documents, and Knowledge easier to maintain and evolve.
Original PR description
Enterprise counter-part. https://github.com/odoo/odoo/pull/279133
5 changes
Resolved issues and error corrections
This fix prevents the Accounting Journal Report from failing when an invoice contains a tax that was originally a group of taxes but was later changed to a percentage tax. Businesses can continue accessing audit reports reliably after tax configuration changes.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
Users can now click and edit custom fields directly in the Documents list view without first activating another standard field. This makes customizations made through Studio work as expected and reduces extra steps for document management users.
Original PR description
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The…
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The user has to first click a standard editable field (like "Owner") to put the row into edit mode before they can modify the custom field. This occurs because we use a hardcoded whitelist (`editableColumns`) of standard fields allowed to trigger edit mode. Custom fields (`x_`) are missing from this static list. This commit resolves the issue by dynamically injecting visible, non-readonly custom fields into the `editableColumns` whitelist. This allows user-created fields to be edited inline as expected. **Steps to reproduce:** - Documents > Studio > List view > Add any field that accepts user input (e.g. Text/char) > save/exit - In the same Documents list view > select a row > click the cell belonging to the newly created field > observe that the row does not enter edit mode - In the same Documents list view > select a row > click a standard editable cell, then click the cell belonging to our newly created field > observe that this then allows us to edit our field **Current behavior before PR:** - Custom fields do not trigger inline edit mode **Desired behavior after PR is merged:** - Custom fields trigger inline edit mode opw-6378102 Forward-Port-Of: odoo/enterprise#125239
Payroll decimal precision settings will no longer be reset to default values when the payroll module is upgraded. This protects company-specific payroll rounding and rate configurations from being silently overwritten.
Original PR description
decimal.precision records are user-configurable settings that may be adjusted per company needs. With noupdate="0", every module upgrade resets the 'Payroll' and 'Payroll Rate' precision values back to their defaults, silently discarding any customization made by the user. This is inconsistent with the standard pattern used across Odoo modules. For example, the 'quality' module correctly loads its decimal.precision records with noupdate="1". The same convention is followed in core addons such as 'product' and 'account'. The forcecreate="True" attribute already ensures the records are created on fresh installations, so noupdate="1" only prevents overwriting existing values on upgrade — which is the expected behavior for configuration data.
Audit reports now use the company selected for the report instead of defaulting to the user's main company. This ensures accounting report headers show the correct company address when working across multiple companies.
Original PR description
When adding the accounting reports to the audit report, we browse the reports with the request's environment which is defaulting to the user's main company. As a result, the company's address displayed in the reports' header is not correct if we generate the audit report for any other company with a different address. https://github.com/odoo/enterprise/blob/aaab137897e6ad794247470e48d5ea91382577a3/account_reports/data/pdf_export_templates.xml#L85 We propose to inject the correct company in the report's environment. opw-6373956
Manufacturing planning tests were updated to match the latest forecast behavior, which now includes replenishment planned later on the current day. This helps ensure planning suggestions remain reliable when same-day demand is considered.
Original PR description
Updated the forecast suggestion test expectations after monthly demand was updated to count the full current day, so same-day orderpoint replenishment moves scheduled later in the day are also included Community PR: odoo/odoo#262435 TaskID-5490137
6 changes
Resolved issues and error corrections
The accounting reports now handle cases where a tax was originally part of a tax group but was later changed. This prevents the Journal Report from failing and helps users continue auditing invoices without disruption.
Original PR description
**Steps to reproduce:** - Install account_reports - Create a tax * Tax Computation: Group of Taxes * Definition: [Add a tax] - Create an invoice with that tax - Confirm the invoice - Edit the tax by changing "Tax Computation" to "Percentage" - Go to "Accounting / Reporting / Audit Reports / Journal Report" **Issue:** A KeyError is raised. **Cause:** While generating the data, a group of taxes is found in the journal items. When trying to retrieve its info from the dict listing the groups of taxes, its ID is not found but the system assumes that it's present. opw-6377465 Forward-Port-Of: odoo/enterprise#125291
Quotations created from repair orders linked to helpdesk tickets now correctly use the salesperson assigned to the customer. This prevents missing salesperson information on sales documents and helps teams keep ownership and follow-up responsibilities accurate.
Original PR description
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to…
Currently, when a quotation is created from a repair order generated from a helpdesk ticket, the salesperson is not set on the quotation even if the customer has a salesperson assigned. **Steps to Reproduce:** - Install `helpdesk_repair`. - Go to `Helpdesk` > `Configuration` > `Helpdesk Teams`. - Open a team recod and enable `Repairs`. - Create a `contact/customer` with a `salesperson` assigned. - Go to `Helpdesk`, create a ticket for that `customer`, and select the `helpdesk team` configured above. - Click `Repair`, then click `Create Quotation`. - Open the quotation and check the `Salesperson` field in the `Other Info` tab. **Current behavior:** The Salesperson field on the quotation remains empty. **Expected behavior:** The Salesperson field on the quotation should inherit the salesperson assigned to the selected customer/contact. **Cause of the issue:** When a repair order is created from a helpdesk ticket, default_user_id [1] is passed in the context . This value is propagated when creating the repair order [2] . Later, when creating the quotation from the repair order [3], the same context is reused. Because default_user_id is already present in the context, it overrides the precomputation of user_id from the customer. As a result, user_id is initialized with an empty value and remains unset. **Fix:** This commit ensures that default_user_id is removed from the context before creating the sale order. Without a default value for user_id, the field is correctly precomputed from the selected customer, and the salesperson is properly assigned. [1]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L52 [2]- https://github.com/odoo/enterprise/blob/2662932c7ac8ebf3ed5a05d44d7ebfaff869fcbd/helpdesk_repair/models/helpdesk_ticket.py#L36-L40 [3]: https://github.com/odoo/odoo/blob/29328b8fccff833c14de317b51f3b4e5a8c40f75/addons/repair/models/repair.py#L357 opw-6344939 Forward-Port-Of: odoo/enterprise#122980
This commit fix the regex used in `street_split` to be more complient. Before: address format was "street_name street_number - street_number2" Now, street_number can be in front of street_name. Format is also less strict, allowing multiple numbers in the street_name without skipping the building number. Linked: https://github.com/odoo/enterprise/pull/121674 task-6317758
Original PR description
This commit fix the regex used in `street_split` to be more complient. Before: address format was "street_name street_number - street_number2" Now, street_number can be in front of street_name. Format is also less strict, allowing multiple numbers in the street_name without skipping the building number. Linked: https://github.com/odoo/enterprise/pull/121674 task-6317758
## Problem `pttExtensionHookService` registers a global `window.addEventListener("message", ...)` handler that reads `data.from` without checking that `data` is defined first: ```js browser.addEventListener("message", ({ data, origin, source }) => { const rtc = env.services["discuss.rtc"]; if ( source !== window || origin !== location.origin || data.from !== "discuss-push-to-talk" || // <- crashes if data is undefined (!rtc && data.type !== "answer-is-
Original PR description
## Problem `pttExtensionHookService` registers a global `window.addEventListener("message", ...)` handler that reads `data.from` without checking that `data` is defined first: ```js…
## Problem
`pttExtensionHookService` registers a global `window.addEventListener("message", ...)`
handler that reads `data.from` without checking that `data` is defined first:
```js
browser.addEventListener("message", ({ data, origin, source }) => {
const rtc = env.services["discuss.rtc"];
if (
source !== window ||
origin !== location.origin ||
data.from !== "discuss-push-to-talk" || // <- crashes if data is undefined
(!rtc && data.type !== "answer-is-enabled")
) {
return;
}
...
```
Any same-window, same-origin `postMessage` sent by an unrelated browser
extension (a common content-script <-> injected-script pattern) can carry
`data === undefined`. The `source !== window` and `origin !== location.origin`
checks only filter out cross-window/cross-origin messages, so a same-origin
message from any other extension reaches this handler and crashes with:
```
TypeError: Cannot read properties of undefined (reading 'from')
```
This surfaces as an uncaught client error on any page with Discuss loaded,
after some time, unrelated to what the user is doing. The Discuss
push-to-talk extension itself does not need to be installed to trigger it,
since the crash happens before checking whether the message actually
originated from that extension.
## Solution
Use optional chaining (`data?.from`) so unrelated same-origin messages with
no `data` are safely ignored instead of crashing.
## Verification
- Reproduced against the live production `web.assets_web.min.js` bundle
(traceback matches exactly).
- Confirmed the bug is still present in the latest `18.0` of both `OCA/OCB`
and `odoo/odoo` (no newer commit touches this file since
`dc58ef1ad904`, which fixes an unrelated issue).Before this commit, the unread banner could stop showing in a channel until it was left and opened again: - open a channel with unread messages - click "Mark as Read" - read the same channel from another device - receive a new message: the server counter increases, still no banner This happens because an implicit mark as read freezes the local unread state, so the banner stays in place while the user reads. The problem is that it stays frozen even after the banner is gone, and never fol
Original PR description
Before this commit, the unread banner could stop showing in a channel until it was left and opened again: - open a channel with unread messages - click "Mark as Read" - read the same channel from another device - receive a new message: the server counter increases, still no banner This happens because an implicit mark as read freezes the local unread state, so the banner stays in place while the user reads. The problem is that it stays frozen even after the banner is gone, and never follows the server counter again. This commit freezes that state only while something is still unread locally. This also fixes the flaky test "no unread message banner after message is deleted". https://runbot.odoo.com/odoo/error/242776
Issue: The MyInvois payload computed `cbc:PrepaidAmount` as `amount_total - amount_residual`, treating every reconciled payment as a prepayment. A payment made on or after the invoice date is an ordinary settlement, not a deposit, but the code recognized it as one anyway. The values reported for `PrepaidAmount` were wrong regardless of the invoice date, and for a fully paid invoice this also collapsed `PayableAmount` to 0.00, which LHDN rejects. Root Cause: LHDN only considers a reconciled
Original PR description
Issue: The MyInvois payload computed `cbc:PrepaidAmount` as `amount_total - amount_residual`, treating every reconciled payment as a prepayment. A payment made on or after the invoice date is an…
Issue: The MyInvois payload computed `cbc:PrepaidAmount` as `amount_total - amount_residual`, treating every reconciled payment as a prepayment. A payment made on or after the invoice date is an ordinary settlement, not a deposit, but the code recognized it as one anyway. The values reported for `PrepaidAmount` were wrong regardless of the invoice date, and for a fully paid invoice this also collapsed `PayableAmount` to 0.00, which LHDN rejects. Root Cause: LHDN only considers a reconciled payment a genuine deposit if it was received before the invoice date. The code applied no date condition at all, so any payment reconciled against the invoice was added to `PrepaidAmount` and reduced `PayableAmount` accordingly. Fix: Only sum reconciled payment partials whose date is strictly earlier than the invoice date as prepaid, so regular payments are no longer misclassified as deposits. As a safety net, if the valid prepaid sum still covers the full invoice amount (e.g. a full advance payment), reset it to 0 so `PayableAmount` always reflects the full amount_total instead of being reported as 0. Also omit the `PrepaidPayment` node entirely when there is no genuine prepayment, rather than emitting it with a 0.00 amount. [Task-6404296](https://www.odoo.com/odoo/my-tasks/6404296) Forward-Port-Of: odoo/odoo#278010
1 change
Resolved issues and error corrections
When a manufacturing order consumes components into negative stock and a later receipt revalues those component moves, only the component valuation was corrected. The finished product kept its initial cost and the production account stayed unbalanced. Steps to reproduce: ------------------- * Configure a finished product and a component in AVCO with automated or manual inventory valuation * Add a BoM with 10 components per finished product * Purchase and receive 5 components at $5/unit *
Original PR description
When a manufacturing order consumes components into negative stock and a later receipt revalues those component moves, only the component valuation was corrected. The finished product kept its…
When a manufacturing order consumes components into negative stock and a later receipt revalues those component moves, only the component valuation was corrected. The finished product kept its initial cost and the production account stayed unbalanced. Steps to reproduce: ------------------- * Configure a finished product and a component in AVCO with automated or manual inventory valuation * Add a BoM with 10 components per finished product * Purchase and receive 5 components at $5/unit * Manufacture 1 finished product, forcing consumption of 10 components * Purchase and receive at least 5 more components at $10/unit > Observation: A revaluation entry is created on the component move of the MO (e.g. 0 qty, -$25), but no matching revaluation is created on the finished product. The FG stays valued at $50 instead of $75 and the WIP/production account is not balanced. Why the fix: ------------ FIFO vacuum corrections were only propagated through `_post_fifo_vacuum` for real-time valuation layers. Manual periodic vacuum SVLs were ignored, so the MRP hook never ran for the common test and production setups. Pass manual and real-time vacuum SVLs to the hook, and mirror the component correction onto the finished product move of the related done MO. opw-6232734