Daily updates from Odoo
Navigate
Branch
Monday, October 13, 2025
230 changes
9 changes
Resolved issues and error corrections
This fix prevents failures when creating Indian GST return records for tax units with multiple companies. The system can now find a valid purchase journal from any company in the tax unit instead of only checking the main company.
Original PR description
Before this PR: - The system searched for a purchase journal only in `company_id`. - In a tax unit with multiple companies, if the main company had no purchase journal configured, record creation failed with a 'NOT NULL constraint violated' error. After this PR: - The journal search now checks all companies in `company_ids` (or falls back to `company_id`), - allowing the system to find a valid purchase journal across the tax unit. OPW: 5159518 Forward-Port-Of: odoo/enterprise#96919 Forward-Port-Of: odoo/enterprise#96838
This update adds safeguards so Danish Nemhandel connections are moved to test/demo mode when a database is neutralized. It helps prevent accidental registration or document sending through production services in copied or test environments.
Original PR description
To avoid sending/registering on production, add a neutralize script. The existing proxy client are put in demo mode. The new connections will be registered on the test server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229934
The Indian localization test setup was adjusted so it no longer depends on US accounting data when demo data is unavailable. This makes automated checks more reliable and avoids false failures during development or release validation, without changing customer-facing functionality.
Original PR description
Standalone `l10n_in` tests were failing when running without demo data because outside-India companies (e.g., US) were defaulting to their country-based chart of accounts. This required the `l10n_us_account` module, causing errors when the module was not installed. <img width="518" height="28" alt="image" src="https://github.com/user-attachments/assets/748663a0-f329-459c-b0e8-0c3de7019258" /> This commit adapts the test cases to run without l10n_us_account dependency. task- 5116352 Forward-Port-Of: odoo/odoo#230041
Changing a coupon reward on a confirmed sales order now updates the coupon's remaining points correctly. This prevents customers from losing or retaining the wrong number of points when a discount reward is switched after order confirmation.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10…
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10 points; 5. use coupon code on a confirmed order; 6. select 10% discount reward; 7. change to a 50% discount reward; 8. check coupon point total. Issue ----- Even though the 5 point reward was used, only 4 out of 10 points remain. Cause ----- When updating the reward line of a confirmed order, it keeps track of point cost changes before & after a write. Its purpose is to restore back the point difference on the coupon record. The issue is that while point changes are stored, coupon changes are not. When updating reward lines, `_reset_loyalty` is used, which removes the `coupon_id` from the lines. As a consequence, attempting to restore the point difference on `line.coupon_id` after an update, it writes to an empty record. Solution -------- Store both coupons & their used points before write. After write, restore the previous points to the previous coupon, and subtract the current point cost from the current coupon. This way, any combination of coupon/point changes should have the points updated as expected. opw-4910922 Forward-Port-Of: odoo/odoo#230907 Forward-Port-Of: odoo/odoo#222054
Fixes an issue where confirming a batch transfer could lose barcode scanning settings, causing location barcodes such as WH-Stock to be read incorrectly. This helps warehouse users scan batch deliveries reliably after confirmation without manual workarounds.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
This fixes a Sales issue where automated checks could fail if a customized sales order line view showed another field before the product field. It helps keep Sales customizations more reliable and reduces false test failures during deployments.
Original PR description
To reproduce: 1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:…
To reproduce:
1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:
https://github.com/odoo/odoo/blob/18.0/addons/sale/views/sale_order_views.xml#L521 making the field `display_type` visible
2. Run the tests of `sale` module
=> `sale` module tests will fail on test `test_sale_combo_configurator_preconfigure_unconfigurable_ptals`
```
FAILED: [18/22] Tour sale_combo_configurator_preconfigure_unconfigurable_ptals → Step Verify that configurable ptals are now configured (trigger:
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")).
Element (
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")) has not been found.
TIMEOUT step failed to complete within 10000 ms.
```
see runbot build fail at:
https://runbot.odoo.com/runbot/build/89552334
The issue happen as - for some dark magic JS/XML reason - adding the field before product_id make fail the step to click the checkbox using the span.
Fix was suggested by PIPU to solve/workaround the issue
In practice, this issue was discovered accidentally with a customisation which was willing to add a custom field at the start of the list
opw-5068699
Forward-Port-Of: odoo/odoo#228029Maintenance equipment pages now open even when customized workflows leave repair or request dates empty. This prevents a data entry edge case from blocking users from viewing equipment records while still keeping the maintenance request in related calculations.
Original PR description
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them…
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them from opening equipment views that displayed fields that depended on it. Steps to reproduce: - Create new maintenance request for an equipment - Put maintenance request into a `maintenance.stage` where `done=True` (e.g. "Repaired") - Force `close_date` to not be `readonly` in form view + set it to `False` - Try to open the assigned equipment's form view Expected result: Form view opens without issue Actual result: `unsupported operand type(s) for -: 'bool' and 'datetime.date'` Issue was due to `mttr` calculation in `_compute_maintenance_request` not expecting `close_date` to be `False`. Since we want the request to still be considered for the rest of the compute, we count its "Time to Repair" as 0 in this case since we cannot use infinity in this case. Additionally, we also gracefully fail in the same way in case `request_date` is also forced to be `False` since it is not a mandatory field and can cause the same issue. 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#230942 Forward-Port-Of: odoo/odoo#230821
Appointment video call links now use the correct website domain tied to the appointment type. This prevents customers from receiving links with the wrong company or website address in multi-company, multi-website setups.
Original PR description
**Steps to reproduce:** - Create 2 companies - Create a website for each company - Set a custom website domain on the second one - Create appointement type for each website - Create an appointement on both websites - The link created for the video call has the wrong base for one of them **Issue:** Appointment `get_base_url` finds its base_url without considering the current website. **Fix:** Compute the base_url according to the appointement type to ensure the current website is taken into account. opw-4880715 Forward-Port-Of: odoo/enterprise#96826 Forward-Port-Of: odoo/enterprise#92734
Fixed an issue where lunch orders could be incorrectly archived after repeated Receive actions or when similar orders already existed. This keeps orders visible and ensures quantities are only merged when the target order can actually be updated.
Original PR description
**Issue** The lunch order merge logic was causing orders to be unexpectedly archived when they shouldn't be. Users would see their orders disappear from the list view after certain operations like…
**Issue** The lunch order merge logic was causing orders to be unexpectedly archived when they shouldn't be. Users would see their orders disappear from the list view after certain operations like clicking "Receive" multiple times or when trying to merge orders with existing ones in immutable states. **Steps to Reproduce** 1st problem - Create a lunch order - From the order list view, select the order and click the "Receive" button - Select and click the "Receive" button again on the same order - The order gets archived and disappears from the view 2nd problem - Create a lunch order - From the order list view, select the order and click the "Receive" button - Place another order for the same product as before - From the order list view, once the second order is set to received, it gets archived and the update quantity logic not triggered **Root Cause and Solution** 1st problem: When searching for matching orders to merge, the current order being processed could match itself, leading to self-deactivation. Fixed by adding matching_lines = matching_lines - line to exclude the current record from potential merge targets. 2nd problem: The merge logic was trying to combine new orders with existing "sent" and "confirmed" orders, but the update_quantity method correctly excludes these states since they shouldn't be modified once sent/received. This created a mismatch where orders would be archived but quantities wouldn't update. Fixed by excluding "sent" and "confirmed" states from merge target searches entirely. Task ID: 5123211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229084
6 changes
Resolved issues and error corrections
The Indian localization test setup was adjusted so standalone tests no longer depend on the US accounting module when demo data is unavailable. This reduces test failures and improves reliability for maintaining the Indian localization without affecting end users.
Original PR description
Standalone `l10n_in` tests were failing when running without demo data because outside-India companies (e.g., US) were defaulting to their country-based chart of accounts. This required the `l10n_us_account` module, causing errors when the module was not installed. <img width="518" height="28" alt="image" src="https://github.com/user-attachments/assets/748663a0-f329-459c-b0e8-0c3de7019258" /> This commit adapts the test cases to run without l10n_us_account dependency. task- 5116352 Forward-Port-Of: odoo/odoo#230041
The commission achievement report now uses the latest end date from relevant commission plans as the default in all cases. This prevents reports from accidentally covering too short a period, helping sales teams and managers see complete commission results.
Original PR description
When there is active_plan_ids in the context the date_to are the max of plans' date_to when not it's the min, this is wrong it should be the maw as well
This fix improves commission reporting reliability by ensuring related adjustment logs generate distinct achievement records. It prevents rare duplicate identifier collisions that could cause commission achievements to be merged or reported incorrectly.
Original PR description
This commit 5b6fdda126e4cfa5ebf92f7b96d1805f6c4b992b introduce an entropy date to avoid having two separate achievment.report record with the same ID. Entropy date for log where based on the write_date, this commit 03d1ee3495a4936fbff0d21743bb784c85b50b12 add the sign of the amount. Unfortunatly this is not enough, the adjustment after the transfer can be positive as well and thus two achievment ends-up with the same ID anyway. This commit use the id of the log to add more entropy to the entropy_date, since log are created in the same transaction, they are likely to have id just seperate by one or only few number, id % 10 seems enough, therefore two log on the same order, with the same create_date will have different entropy date and end up with a different id.
This fix preserves barcode scanning settings when a warehouse batch transfer is confirmed. It prevents location barcodes such as WH-Stock from being misread character by character, helping warehouse staff continue batch picking without scan failures.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
This update adds safeguards so Danish Nemhandel connections are neutralized in non-production copies. Existing proxy clients are switched to demo mode, and new registrations use the test server to avoid unintended live sending or registration.
Original PR description
To avoid sending/registering on production, add a neutralize script. The existing proxy client are put in demo mode. The new connections will be registered on the test server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229934
Point of Sale payments made through a payment terminal now complete automatically when cash rounding is applied. This prevents staff from having to manually validate fully paid orders, reducing missed validations and checkout mistakes.
Original PR description
Ensure that when a payment is made via a payment terminal and cash rounding is applied, the payment is automatically validated once the response is received. Previously, validation did not always occur because we relied on `get_due` is not exactly what is left to pay, as it does not account for cash rounding rounded amounts. The condition for auto-validation was simplified, since `is_paid` already checks whether there is nothing left to pay. Thus, using `get_due` is redundant. Steps to reproduce: 1. Create a cash rounding and set it on the POS. 2. Sell a product priced at e.g. 1.99 EUR, paid via a terminal (e.g. Worldline). 3. Notice the payment is not auto-validated and requires manual validation, which can lead to mistakes or missed manual validations. opw-4862684 Forward-Port-Of: odoo/odoo#231034 Forward-Port-Of: odoo/odoo#228608
6 changes
Enhancements to existing features
Unpaid leave and unpaid sick leave days are now excluded from UAE end-of-service and provision salary calculations, making payroll results more accurate. End-of-service payslips also display the total unpaid leave days for clearer employee and HR review.
Original PR description
This commit excludes the Out Of Contract Unpaid Leaves and Unpaid Sick Leave days from the EoS and EoS Provision Salary Rule Calculations. We also show the total number of unpaid leave days on the EoS payslip. task-4886104 Forward-Port-Of: odoo/enterprise#95465
Resolved issues and error corrections
This update adjusts an internal test workaround for Gantt scheduling so automated checks continue to run correctly after changes in the testing framework. It is limited to unit tests and does not change business functionality or user workflows.
Original PR description
## Pull Request HOOT 37 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Community: https://github.com/odoo/odoo/pull/230556 Forward-Port-Of: odoo/enterprise#96647
Employee contracts in Swiss payroll now only show insurance options that belong to the relevant company. This prevents accidental selection of insurance records from another company in multi-company environments, improving data accuracy and payroll setup.
Original PR description
Currently, in a multi-company setup, you are able to select insurances from other companies on the employee contract task-5157106 Forward-Port-Of: odoo/enterprise#96821
SEPA payment files will now mark payments as high priority only for Belgian companies. This helps companies in other countries avoid unnecessary bank fees caused by high-priority processing.
Original PR description
Having priority set as HIGH for SEPA payments can induce extra fees (ex. in CH). This commit only sets the priority to HIGH for BE companies. task-4874217 Forward-Port-Of: odoo/enterprise#96794 Forward-Port-Of: odoo/enterprise#95420
UrbanPiper POS orders now apply the correct taxes when a point of sale is set up under a branch company. This prevents undercharging or inaccurate tax reporting in multi-branch businesses, including cases where taxes are split into sub-taxes.
Original PR description
Steps to reproduce: --- - Install `pos_urban_piper`. - Create a branch under *Main Company*. - Switch to the new branch. - Create a POS config in this branch and set up UrbanPiper. - Sync "Apple Pie". - Place an order with "Apple Pie". Issue: --- - The 15% tax defined on Apple Pie is not applied on the orderline. Cause: --- - While creating the order line, the tax company was compared directly with the POS config’s company. In this case, the tax belongs to the parent company, while the POS config belongs to a child company. Fix: --- - Compare the `root_id` of both companies instead of the direct company ID to ensure taxes are applied correctly in multi-branch setups. - Additionally, handled the case where a main tax has sub-taxes (e.g., 5% GST split into 2.5% SGST and 2.5% CGST). In such cases, we now fetch the tax type from the sub-taxes instead of the main tax. Task-5050682 Forward-Port-Of: odoo/enterprise#93467
Mexican DIOT reports now identify United Kingdom transactions with the correct country code instead of grouping them under "Other country." This helps businesses produce more accurate tax reporting for UK-related records.
Original PR description
The DIOT country adaptation map lacked the ISO 3-letter code for the UK, causing records with country 'GB' to be reported as 'ZZZ' ("Other country").
Added mapping 'GB' → 'GBR' to ensure correct DIOT country code generation.

Forward-Port-Of: odoo/enterprise#9677148 changes
Enhancements to existing features
The payroll contract salary test flow was updated to stay aligned with recent underlying changes. This helps ensure the employee salary configuration process continues to be validated reliably without changing the user-facing experience.
Original PR description
This commit handles the change in test case due to the modification in the following commit [1]. [1]=https://github.com/odoo/odoo/pull/227819/commits/360b384ba4e24 Forward-Port-Of: odoo/enterprise#96833
Additional automated tests now cover key appointment booking scenarios, including capacity handling, unavailable time slots, cart bookings, invoice confirmation, and event creation. This helps reduce the risk of booking errors for customers and staff across appointment sales and payment flows.
Original PR description
\* = website_appoinment_sale, appointment_account_payment Add tests to ensure correct behaviour for the various scenarios. The following tests are added: - Users/resource's capacity computation when manage capacity is on and off. - Unavailability computation of users/resources in the `calendar.event`. - Check the bookings of user/resource in the cart for the availability after the invoice is confirmed. - Creation of the actual event when the booking from the cart is confirmed. Task-4919317 Forward-Port-Of: odoo/enterprise#96587 Forward-Port-Of: odoo/enterprise#91676
Payroll now shows clearer warnings and errors on payslips, helping payroll teams understand and resolve salary issues faster. Missing bank account information is treated more seriously when payroll accounting is enabled, reducing the risk of payment problems during pay runs.
Original PR description
Improved issues shown in payslip warnings and errors, fixed multiple tracebacks and errors related to the new issues system with payruns and payslips Task: 5065090
The Belgian payroll DMFA work locations list can now be edited directly from the list view. This makes maintaining work location information faster and reduces extra navigation for payroll administrators.
Original PR description
task-5156915
The Documents app now offers Duplicate and Move actions directly from the left-side cog menu, making common folder management tasks easier to find. The shortcut option is also available in more appropriate places while respecting user permissions and excluding special areas such as Company, Recent, and Trash.
Original PR description
- This commit adds the `Duplicate` and `Move` options on the left cog wheel. - Adapt the conditions for the `Add to shortcut` so that it is available in the cog menu, except for folders which already have a shortcut, moved used `DocumentsCogMenuItemOperation` for `DocumentsCogMenuItemShortcut` to avoid code duplication. - These options will not be there when the user lacks access, and for special roots like `All Company, Recent, Trash ... Task-4949092
The Belgian payroll reporting menu has been cleaned up by removing several specialized options from the main menu. Work entry exports are still available from the Work Entry cogwheel when relevant, making the interface less cluttered while keeping export actions accessible in the right context.
Original PR description
removed the menu items: Meal Vouchers, Export Work Entry Types, and Departure: Notice Period & Holiday Attests from the top menu bar but added the Export Work entry types to the cogwheel inside the work entry with some limitations such as to appear only when: - The company is in Belgium (country code: BE). - The Work Entry page (not the employees page for example). - With all views (e.g. list, grantt, ...etc.) but the form view. - We have any of the export types installed, such as the group_s, ucm, sd_worx... etc. task-5005925
The WhatsApp app now uses Odoo's Discuss conversation system more directly. This simplifies how WhatsApp messages connect with internal conversations, helping keep messaging behavior more consistent and easier to maintain.
Original PR description
Use discuss channel directly
UAE payroll now handles all sick leave types through a single salary rule instead of separate rules for each type. This simplifies payroll configuration and accounting setup while keeping sick leave calculations consistent.
Original PR description
Originally, each sick leave in the UAE's localization has its own salary rule. The logic for all the sick leave types has been grouped into one salary rule.
Manufacturing teams can now choose the order of quality checkpoints within operation instructions. This restores ordering flexibility that existed before a redesign, making work instructions easier to organize and follow.
Original PR description
- Sequence was added to give flexibility in ordering quality points inside operations. **Note:** this was already there in past versions, it was just forgotten in the latest redesign: https://www.odoo.com/odoo/project/966/tasks/5005235 Task: 5110982 Forward-Port-Of: odoo/enterprise#95526
Recruiters can now use the Generate Offer button more than once for the same applicant. This makes it easier to prepare or revise multiple salary offers without being blocked after the first one.
Original PR description
Purpose: Modified the visibility attribute on the Generate Offer button in the applicant view so the it allows the generation of multiple offers for the same applicant Task ID: 5088931 Forward-Port-Of: odoo/enterprise#94731
The referral page actions have been reorganized to make the most important option, Job Page, easier to find. Send and Share actions are now grouped into separate dropdowns with consistent icons and alignment, reducing clutter for users managing referrals.
Original PR description
Changes Kept "Job Page" as the first button. Grouped "Send" actions under a dropdown Grouped "Share" actions under a second dropdown Standardized icons and alignment for consistency Task ID: 5017390
Overtime rules can now be created without automatically linking them to a work entry type. When a work entry type is selected, the overtime rate is controlled by that type and cannot be manually changed, helping keep payroll calculations consistent.
Original PR description
If Work Entry module is installed --> Make the rate readonly within the form view of the attendance overtime rule. changes: - work_entry_type is not required anymore on ot (overtime) rules. - ot rules won't be assigned a default work_entry_type. - if there's no work_entry_type assigned on the ot rule, the user can manually edit the rate. - if there's a work_entry_type, the rate becomes readonly within the view and computed from the work entry type. Task-5107738
Indonesian payroll now calculates net salary and taxes more accurately by including company contributions, employee-specific payslip data, and updated statutory rounding rules. The update also adds a fixed allowance salary rule and improves tests to help ensure payslip results match local payroll requirements.
Original PR description
* Update the calculation of net salary in indo localization to use company contribution category too * Update the domain search for searching gross / pph21 yearly so it search only the current employee's payslip * Move Biaya Jabatan threshold rule to apply after the calculation instead of before (to follow the rules of 500.000 / payslip(month)) * Add rounding to pph21(round half up) and PKP (round down to nearest thousand) * Add new salary rule (Fixed Allowance) * Fix and add new unit test Task: 4967867
Indian payroll reports now present salary figures more clearly with better alignment, currency symbols, and improved ordering of key totals. The salary statement also corrects the Cost to Company amount so it reflects the actual wage, while the yearly salary report is easier to use with the current year selected by default and years shown newest first.
Original PR description
- Salary Register Report: - Aligned character fields to the left and number fields to the right - Salary Statement Report: - Aligned all amount fields to the right and added currency symbols - Moved 'Net Salary' field before 'Cost to Company' and made it bold - Corrected 'Cost to Company' amount to reflect actual wage - Labor Welfare Fund Report: - Aligned amounts to the right and added currency symbols - Yearly Salary by Employee Report: - Set current year as default in the wizard - Displayed years in descending order - Aligned month name to the left in the generated PDF task-5026145
The payment initiation status is now shown only when it applies to supported outbound SEPA credit transfer batch payments. This reduces confusion by hiding irrelevant default status information in other payment scenarios.
Original PR description
Prior to this commit, the PIS status column is the batch payment form view was always visible and always had `uninitiated` as default value. This leads to confusion as it can be irrelevant for some batch payment usecases. With this commit, the PIS status is now only visible when the account.online.link associated with it has payments enabled, the batch payment is outbound and is using the SEPA CT payment method. Basically, the only usecase we support. Task ID: 5156710
Belgian payroll users can now manage Group Insurance Exports through standard list and form screens instead of a temporary wizard. This makes the process more consistent with other payroll exports and improves maintainability across payroll export providers.
Original PR description
In this PR we: - Converted the Group Insurance Export from a wizard-based flow into standard list and form views. - Extracted common fields and views from both Group Insurance Export and HR Work Entry Export mixin into a new hr.export.mixin - Updated Group Insurance Export and HR Work Entry Export to inherit from hr.export.mixin and override their views. Related task: 5010866.
This change updates internal data-query handling used by several accounting and reporting areas, making the underlying system simpler and easier to maintain. Business users should not see workflow changes, but the improvement helps reduce future maintenance risk across financial reports and related tools.
Original PR description
odoo/odoo#230715
Users are now notified as soon as their payment initiation is activated, instead of waiting for the next account synchronization. This reduces delays in communicating activation status and adds test coverage for the payment verification flow.
Original PR description
Before this we sent activation emails when synchronizing accounts, this could cause a delay for the users knowing when their payment initiation was activated. Now, we send it as soon as we receive the webhook from Odoofin. This commit also adds tests for the KYC flow. Part of: 4487895 Forward-Port-Of: odoo/enterprise#93971
The Belgian salary package demo data now uses an email address that matches Laurie Poiret's login. This avoids duplicate-looking contact details in the user form and keeps demo records cleaner for demonstrations and testing.
Original PR description
laurie poiret uses a different login from her email. Which is technically fine but leads to both of them appearing in the user form which we don't want. task-5130854 [related]: odoo/odoo@db3dee12d7c17ad485800d000ec4cdd87fcfd18b Forward-Port-Of: odoo/enterprise#96591
This update prepares the Discuss action panel framework so it can be shared by more types of actions in future releases. There is no current functional change for users; the existing thread action behavior remains the same while the code is made more consistent for upcoming improvements.
Original PR description
Before this commit, action panel definition was a feature only available in thread actions. This commit moves definition to all actions, to move closer to same feature-set to all discuss actions. Summary of the changes: 1. `panelOuterClass` has been renamed to `actionPanelOuterClass` 2. `toggle` has been removed (always set for action panel) 3. `open` and `close` renamed to respectively `actionPanelOpen` and `actionPanelClose`. 4. `open` is specific to actions with action panel. Other actions must use `onSelected` like other discuss action definitions. Functionally this commit makes no change: action panel is still only used by thread actions. Future commits will make use of action panel for the composer pickers and will also make further improvements to code around action panels.
Resolved issues and error corrections
This update adds test coverage to ensure new Helpdesk tickets can be created when a stage has a “Days to rot” value set. It helps prevent a crash that could block support teams from logging new customer requests.
Original PR description
Currently an error occurs when user creates the helpdesk ticket. Steps to Reproduce: - Install the `helpdesk` module. - Go to `Stages` and, in the `Kanban view`, open the `New Stage` record. - Set a value `greater than 0` in the `Days to rot` field. - Go to `Tickets` and click `New`. `TypeError: unsupported operand type(s) for +: 'bool' and 'datetime.timedelta'` This commit adds a test for this [PR](https://github.com/odoo/odoo/pull/230271). sentry-6927500374 Forward-Port-Of: odoo/enterprise#96507
Payroll salary rules now prevent changes to the salary structure once the rule is linked to an employee property. This helps avoid accidental payroll configuration changes that could affect employee pay calculations.
Original PR description
As some other `hr.salary.rule` fields (like Section and Unit), Salary Structure is now readonly when the rule has a property on an employee. [task-5135927](https://www.odoo.com/odoo/project/1251/tasks/5135927)
This update fixes how payroll finds related work entries after a field name change. It helps ensure payslips use the correct work entry dates and avoids errors caused by outdated date fields.
Original PR description
There is no more date_start and from in work entries. Use date instead. Forward-Port-Of: odoo/enterprise#96840
Fixed an issue where barcode users could see raw formatting code instead of a readable help message after validating a filtered transfer. This improves clarity during inventory receipt workflows and avoids confusing on-screen text.
Original PR description
Issue: ------ When validating a transfer after filtering by scanning a product, the empty help message was shown as raw HTML instead of parsed text. Steps to reproduce: ------------------- 1. Install Barcode. 2. In Inventory, create a receipt with product Pedal Bin. 3. Click Mark as Todo. 4. Open Barcode → Operations → Receipts. 5. Scan the barcode of Pedal Bin. 6. Open the receipt and validate. The helper text is displayed in raw format. Cause: ------ The server returned the help text as a plain HTML string. Since JSON serialization strips Python markup objects, the client received raw HTML, which was not parsed and therefore rendered as-is. Fix: ---- The web client now wraps the help text with `markup()` before display, ensuring the message is parsed and shown in a readable format. opw-5090075 Forward-Port-Of: odoo/enterprise#96655 Forward-Port-Of: odoo/enterprise#95020
Fixes an issue where confirming a batch transfer could lose barcode scanning settings, causing location barcodes like WH-Stock to be read incorrectly. Warehouse users can now confirm batches and continue scanning locations normally, avoiding blocked or failed batch picking workflows.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
Creating a goal from an employee appraisal now correctly uses the employee linked to that appraisal instead of defaulting to the current user. Creating goals directly from the Goals menu no longer pre-fills employee or manager details, reducing accidental assignment errors.
Original PR description
If you go on _appraisals -> any employee -> goals smart button -> new_, it will populate the employee field with the current user. Instead, the field should be filled by the appraisal's user. If the goal is created from the "Goals" menu item directly, then no user / manager should be put by default in the goal's fields. I changed the field's default value to use the employee already passed in the context. I also added some tests to make sure the bug doesn't happen again. task-5048292 Forward-Port-Of: odoo/enterprise#96687 Forward-Port-Of: odoo/enterprise#93522
Salary simulation pages opened from recruitment offers now use the correct company context when loading allowed benefits. This ensures candidates and HR teams see up-to-date benefit values for the relevant company instead of defaults from another company.
Original PR description
in this commit, fixes issue when open simulation page through recruitment offer values of benefits not updated. issue: get only default first company while triggering get white list method. task-4929771 Forward-Port-Of: odoo/enterprise#95866
This update ensures Indian payroll template values are correctly copied when template data is loaded. It prevents missing payroll configuration fields, helping businesses avoid incomplete setup data during payroll configuration.
Original PR description
in this commit, fixes issue when load template data fields
values didn't get copy.
issue:
missing fields in list of whitelisted_fields.
task-5155428
Forward-Port-Of: odoo/enterprise#96694Appointment video call links now use the website tied to the appointment type, so businesses with multiple websites or custom domains get the correct link. This prevents customers from receiving video meeting URLs with the wrong website address.
Original PR description
**Steps to reproduce:** - Create 2 companies - Create a website for each company - Set a custom website domain on the second one - Create appointement type for each website - Create an appointement on both websites - The link created for the video call has the wrong base for one of them **Issue:** Appointment `get_base_url` finds its base_url without considering the current website. **Fix:** Compute the base_url according to the appointement type to ensure the current website is taken into account. opw-4880715 Forward-Port-Of: odoo/enterprise#96826 Forward-Port-Of: odoo/enterprise#92734
The appraisal skills list now scrolls properly on mobile devices, making the justification field and add/remove buttons accessible again. This helps managers and employees complete skill appraisals without missing key fields or actions on smaller screens.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 Forward-Port-Of: odoo/enterprise#96797 Forward-Port-Of: odoo/enterprise#91882
Social Marketing posts now correctly recognize URLs that include comma-separated parameters, so previews no longer cut links at the first comma. This helps users share tracking or parameterized links accurately across social posts.
Original PR description
**Steps to reproduce:** - Go to `Social Marketing` app. - Click on `New Post`. - Select Facebook for preview (should not matter). - Write a message with an URL which have comma-separated parameters. (e.g 'TEST URL https://example.be:8080/path/res-123/ext/?param1=v1,v2,v3') - URL is cut on the first comma in the preview. **Issue:** URL regex did not match URLs containing comma-separated query parameters, causing them to be truncated. **Fix:** Updated the regex to include commas. opw-5042131 Forward-Port-Of: odoo/enterprise#96340 Forward-Port-Of: odoo/enterprise#94220
Individual salary attachments created from a multi-employee salary adjustment now keep the original duration setting. This prevents limited-duration adjustments from incorrectly becoming one-time items, helping payroll records stay accurate.
Original PR description
**Issue** When creating individual attachments from a salary adjustment with multiple employees, the duration_type field was not being copied to the individual records causing all split attachments to default to "One Time" instead of preserving the original duration type. **Steps to reproduce** - Go to Payroll > Employees > Salary Adjustments - Create a new Salary Adjustment for multiple employees - Set Duration to "Limited" and create individual attachments - Open any individual attachment, duration shows "One Time" instead of "Limited" Task ID: 5136664 Forward-Port-Of: odoo/enterprise#96152
Mexican DIOT reports now correctly identify United Kingdom records using the proper country code instead of grouping them under “Other country.” This improves reporting accuracy for businesses with UK-related transactions.
Original PR description
The DIOT country adaptation map lacked the ISO 3-letter code for the UK, causing records with country 'GB' to be reported as 'ZZZ' ("Other country").
Added mapping 'GB' → 'GBR' to ensure correct DIOT country code generation.

Forward-Port-Of: odoo/enterprise#96771Belgian POS users now see a clear “Device disconnected” message when the blackbox device is unplugged or loses connection. This replaces a vague unknown error, helping staff understand and resolve the issue faster.
Original PR description
When the blackbox is being disconnected the user gets "unknown blackbox error" instead of "Device disconnected" explicit message. This PR removes this vague error message introduced in https://github.com/odoo/enterprise/pull/93468 Forward-Port-Of: odoo/enterprise#95587 Forward-Port-Of: odoo/enterprise#95489
This fix prevents completed tax returns from having their deadlines changed when company reminder settings are updated. It also ensures return deadlines are correctly applied for each company in multi-company setups, improving reliability for compliance tracking.
Original PR description
And remove _inverse_deadline_days_delay since _compute_deadline already does everything. To Replicate: - open the returns - mark as completed or complete at least one return - change the deadline_days_delay for that return type - It doesn't change the deadline of completed returns this is working as expected - change the account_return_reminder_day of the company - now it updates the deadline of already existing returns. Forward-Port-Of: odoo/enterprise#95739
Indian GST return processing now looks for a purchase journal across all companies in a tax unit, rather than only the main company. This prevents record creation failures when the main company lacks a purchase journal but another company in the tax unit has one configured.
Original PR description
Before this PR: - The system searched for a purchase journal only in `company_id`. - In a tax unit with multiple companies, if the main company had no purchase journal configured, record creation failed with a 'NOT NULL constraint violated' error. After this PR: - The journal search now checks all companies in `company_ids` (or falls back to `company_id`), - allowing the system to find a valid purchase journal across the tax unit. OPW: 5159518 Forward-Port-Of: odoo/enterprise#96919 Forward-Port-Of: odoo/enterprise#96838
The update stabilizes follow-up report tests that could fail if they started before midnight and continued after midnight. This helps keep automated quality checks reliable without changing customer-facing accounting behavior.
Original PR description
Tests https://runbot.odoo.com/odoo/runbot.build.error/159772 where failing when setUpClass run before midnight and the test itself run at/after midnight because `today` was not the same. As follow-up report divides the lines per partner to due/overdue utilizing `today` in comparison, This resuls in different lines than expected. Forward-Port-Of: odoo/enterprise#96486
Location barcode images are now hidden when the barcode contains characters that cannot be rendered. This prevents upgrade failures for customers with unsupported barcode values while keeping valid barcodes visible.
Original PR description
A new field `barcode_img` was added odoo/enterprise@53d008e9ce11bbf870e5d2f248fd591fa679be0e to display location barcodes in the form view. It uses the `barcode` field of the location, but some clients have values with unsupported characters (e.g., `Ž`, `بيع`) that cannot be encoded in Code128. This caused upgrade failures as such barcodes could not be rendered. Now, Don't show barcode in the form view if it fails to render. opw-5129150 Forward-Port-Of: odoo/enterprise#96523
Fixes an issue where Colombian online shoppers could get stuck on the address step when choosing certain tax obligation options. The checkout now saves the address correctly and continues to delivery, reducing failed orders and support friction.
Original PR description
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and…
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and there is an “expected singleton” traceback in the logs. This is because in the method `_parse_form_data` in `l10n_co_website_sale`, the obligation type field on `form_data` is set to be a list of “type ids” which leads to an error when `convert_to_cache` is called as the browse function in this attempts to convert the list to a tuple of single characters. For example, if the list is ["10"], it gets converted to ("1","0") hence leading to the expected singleton traceback.
Purpose: Instead of passing a form list to form_data,we pass the record set which will correctly set the values in the address, much like how `default_obligations_ids` is also currently set. After this correction, the website address screen will save the address properly and redirect to the delivery screen for further actions.
Steps to Reproduce on Runbot:
1. Create a Colombian company, make sure l10n_co is installed
2. Set the company on the website to this company
3. Ensure that there is a record in the table `l10n_co_edi_obligation_type_ids` with id > 9. Create one if it does not exist.
4. Open the /shop page in incognito mode as a public user.
5. Add a product, go to the checkout page, proceed to the address page.
6. Enter all the information including the Identification Number (e.g. 623.456.789-1). Choose “NIT” in identification type and select the type code from step 3 in the dropdown for obligation type. Choose country “Colombia” along with a state and city
7. Click on "Continue checkout". The page gets stuck in a loading state
forever.
opw-4776301
Forward-Port-Of: odoo/enterprise#90862Creating a work entry without selecting a work entry type no longer causes an error. This keeps HR work entry planning usable even when optional information is left blank.
Original PR description
If the user creates a work entry without a work entry type, it will fetch "false" id work entry type. It raises a traceback task-5078885 Forward-Port-Of: odoo/enterprise#95149
Commission achievement reports now use the latest plan end date as the default end date in all cases. This prevents reports from ending too early when multiple commission plans are involved, giving sales teams and managers more accurate reporting periods.
Original PR description
When there is active_plan_ids in the context the date_to are the max of plans' date_to when not it's the min, this is wrong it should be the maw as well Forward-Port-Of: odoo/enterprise#96526
This fixes an issue where some sales commission adjustments could create conflicting achievement records. The change helps ensure commission reporting remains accurate when multiple related log entries are created at nearly the same time.
Original PR description
This commit 5b6fdda126e4cfa5ebf92f7b96d1805f6c4b992b introduce an entropy date to avoid having two separate achievment.report record with the same ID. Entropy date for log where based on the write_date, this commit 03d1ee3495a4936fbff0d21743bb784c85b50b12 add the sign of the amount. Unfortunatly this is not enough, the adjustment after the transfer can be positive as well and thus two achievment ends-up with the same ID anyway. This commit use the id of the log to add more entropy to the entropy_date, since log are created in the same transaction, they are likely to have id just seperate by one or only few number, id % 10 seems enough, therefore two log on the same order, with the same create_date will have different entropy date and end up with a different id. Forward-Port-Of: odoo/enterprise#96622
This change prevents an uninstall process from failing when worksheet-related database fields have already been removed. It helps avoid incomplete uninstalls that could cause problems when reinstalling dependent modules later.
Original PR description
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks…
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks when uninstalling module `worksheet`:
```
ir.model.data._module_data_uninstall():
... records are deleted ...
ir.model.fields.unlink():
drop column of corresponding fields
delete ir.model.field records
ir.model.unlink():
drop table of corresponding models
ir.model._unlink_if_uninstalling():
self.env['worksheet.template'].search([('model_id', ...)]).unlink()
delete ir.model records
```
The call to `ir.model.unlink()` crashes when searching for worksheet templates, since column `model_id` has been dropped already. This makes the transaction fail, and it is rolled back to a savepoint just before the call to `ir.model.unlink()`. In other words, the uninstallation manages to drop most of the columns that must go, but fails to drop all the tables that must go. And the uninstallation proceeds anyway...
Now consider uninstalling module `resource`. That module defines model `resource.calendar` with required field `name`, and also defines a record in that model (a default calendar). When the module is uninstalled, module `worksheet` is also uninstalled (because it depends on `resource`), and so the situation above happens. Consequently, most of the columns of table `resource_calendar` are dropped, but the table is not. If we reinstall module `resource` after that, the ORM re-creates column `name` (which is `NULL` on the default calendar at least), but fails to add the `NOT NULL` constraint on that column.
The fix consists in avoiding the `search()` above in the ondelete method if the column `model_id` does not exist anymore.
Forward-Port-Of: odoo/enterprise#96845The grid view now keeps all months visible when users turn off weekend display in yearly reports. This prevents missing months in Analytic Reporting and makes year-based views easier to trust.
Original PR description
To reproduce: ============= 1- Go to Analytic Reporting. 2- From the year dropdown, uncheck "Show weekends". → Some months disappear unexpectedly. Problem: ========= Weekend filtering was applied even in year range. In year view, each column is already a full month, so filtering out weekends is incorrect. Fix: ==== Adjust the condition to skip filtering when range is not "month". Weekend logic now only applies to month range grid. community-pr: https://github.com/odoo/odoo/pull/226975 opw-5078200 Forward-Port-Of: odoo/enterprise#96171 Forward-Port-Of: odoo/enterprise#94593
This fixes failing automated tests by ensuring sample products are treated as properly configured items. It helps keep manufacturing planning and rental test coverage reliable after a lead-time rule change for unconfigured products.
Original PR description
This PR addresses the issue where tests were failing due to unconfigured products (no vendor/ no BoM). Now unconfigured products' lead_time is incremented by 365 due to this PR: https://github.com/odoo/odoo/pull/216293 Before this fix: Products have `buy` route by default and no vendor, so they are considered unconfigured products and lead time is incremented by 365, and tests fail as any lead time refers to a date earlier than today would only affect the first period in the MPS which is not intended in the tests. After this fix: Products have `manufacture` route and there is BoM, so they are considered configured products and lead time is calculated normally from BoM which is 0. Task-4779057 Forward-Port-Of: odoo/enterprise#96911 Forward-Port-Of: odoo/enterprise#88766
Features or functions removed from Odoo
A payroll validation that no longer matched the updated work entry date model has been removed. This avoids unnecessary blocking or confusing checks when processing payslips and payroll batches.
Original PR description
With how the work entries have changed from date_to/date_end to only a date, the check did not make sense anymore. This commit removes the check. task-5135966
An unused tooltip setting was removed from document tags after earlier changes made it irrelevant. This keeps the Documents app cleaner and avoids maintaining a field that no longer affects users.
Original PR description
The 'tooltip' field was introduced on document tags categories, but after couple of refactors it ended up unused on document tag. In the previous, stable versions - this commit hid the tooltip from the view While here it is completely removed. opw-4567814 ## Stems from https://github.com/odoo/odoo/pull/210147 https://github.com/odoo/enterprise/pull/79496 # Merge plan - hide `tooltip` in stable - remove `tooltip` in master (from the py in this PR and from the db in the [upgrade PR](https://github.com/odoo/upgrade/pull/8562) ) Forward-Port-Of: odoo/enterprise#86504
Code cleanup and technical improvements
This update reorganizes how WhatsApp message actions reference conversations behind the scenes. It should not change day-to-day behavior, but it helps keep the messaging code clearer and easier to maintain for future updates.
Original PR description
https://github.com/odoo/odoo/pull/231043
17 changes
Enhancements to existing features
Peppol UBL electronic invoices now include the delivery party in the delivery information. This makes exported invoices clearer for recipients by showing who the delivery is for, using the shipping contact when available or the customer name otherwise.
Original PR description
Previously, the Peppol UBL export only covered the mandatory delivery fields and did not include the `delivery party`. This commit adds the `<cac:DeliveryParty>` element under `<cac:Delivery>` to improve the exported information. - Include `<cac:DeliveryParty>` in the `<cac:Delivery>` section of UBL invoices. - Use the shipping partner name if set; otherwise, fallback to the customer name - Keep existing `<cac:DeliveryLocation>` and delivery date logic unchanged. <img width="766" height="306" alt="image" src="https://github.com/user-attachments/assets/d07c1b37-4c6d-42d1-99b4-66c5abc8e298" /> ----- task-5022404 Forward-Port-Of: odoo/odoo#230468 Forward-Port-Of: odoo/odoo#223756
The HR work entry process has been simplified by no longer requiring a work entry type in cases where it is not needed. This reduces unnecessary setup or data-entry friction for HR teams while keeping the change limited to the work entry area.
Original PR description
Removing unneeded function Task-5107738
The Belgian salary package demo data now aligns Laurie Poiret's login and email information. This avoids duplicate-looking contact details appearing in the user form, making demo records clearer for users reviewing the system.
Original PR description
laurie poiret uses a different login from her email. Which is technically fine but leads to both of them appearing in the user form which we don't want. task-5130854 [related]: odoo/odoo@db3dee12d7c17ad485800d000ec4cdd87fcfd18b
Resolved issues and error corrections
This fixes an issue in the Turkish Nilvera integration that could trigger a server error when handling failed HTTP responses. Businesses using this localization should now see the intended error handling instead of an unexpected crash.
Original PR description
The http response object doesn't have a `code` attribute, this commit fixes this typo which has already been fixed in 19.0 as a part of #222869 task-5050516 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228088
This update adjusts customer portal templates so invoices, terms, and sales documents display correctly after a recent template engine change. It prevents missing layout details caused by the new way template information is passed behind the scenes.
Original PR description
In this commit(#197296), the behavior of `<t t-call>` has been updated to support parametric template calls. Variables defined inside a nested <t t-set> within a `<t t-call>` block are no longer visible to the called template due to lazy XML evaluation. This commit updates QWeb templates to: Pass parameters directly as attributes on <t t-call> instead of using inner <t t-set> tags. Before fix: <img width="1875" height="985" alt="image" src="https://github.com/user-attachments/assets/c55d42bc-69a5-42d7-9878-e8334b3cebd9" /> After fix: <img width="1869" height="974" alt="image" src="https://github.com/user-attachments/assets/62286ffe-879a-4741-a83f-7fbb8d94bb2c" /> opw-5152781 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
This fixes an issue where a document selected for a draft chatter note could become linked to the underlying record before the note was posted. Attachments now stay tied to the draft composer until the user posts the message, preventing unintended document links and disruptive preview behavior.
Original PR description
When adding attachment from documents in the composer, link the attachment to the composer and not to the thread as it must be linked to the thread only once the message is posted. How to reproduce: - Install the app documents and crm - Open a lead - In the chatter click on "Log a note" - Then click on "Add from Documents" - Select a document and click on "Add from Documents" - Reload the page without posting the message The attachment selected in document is now linked to the lead which shouldn't be the case. Note that if you do the same for an expense, as the attachment is linked to the expense right away when added, the preview panel open immediately, and you have to reopen "Log a note". That was the original bug detected. Task-5075835
This change prevents Danish Nemhandel electronic invoicing connections from accidentally using production systems in neutralized environments. Existing proxy clients are switched to demo mode, and new registrations are directed to the test server, reducing operational risk during testing or copied database use.
Original PR description
To avoid sending/registering on production, add a neutralize script. The existing proxy client are put in demo mode. The new connections will be registered on the test server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229934
The India localization test setup was adjusted so it no longer depends on the US accounting module when demo data is unavailable. This reduces avoidable test failures and helps keep the India localization more reliable during development and maintenance.
Original PR description
Standalone `l10n_in` tests were failing when running without demo data because outside-India companies (e.g., US) were defaulting to their country-based chart of accounts. This required the `l10n_us_account` module, causing errors when the module was not installed. <img width="518" height="28" alt="image" src="https://github.com/user-attachments/assets/748663a0-f329-459c-b0e8-0c3de7019258" /> This commit adapts the test cases to run without l10n_us_account dependency. task- 5116352 Forward-Port-Of: odoo/odoo#230041
Fixed an issue where changing a coupon reward on a confirmed sales order could deduct the wrong number of points. Coupon balances now stay accurate when customers switch rewards, reducing billing and loyalty program discrepancies.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10…
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10 points; 5. use coupon code on a confirmed order; 6. select 10% discount reward; 7. change to a 50% discount reward; 8. check coupon point total. Issue ----- Even though the 5 point reward was used, only 4 out of 10 points remain. Cause ----- When updating the reward line of a confirmed order, it keeps track of point cost changes before & after a write. Its purpose is to restore back the point difference on the coupon record. The issue is that while point changes are stored, coupon changes are not. When updating reward lines, `_reset_loyalty` is used, which removes the `coupon_id` from the lines. As a consequence, attempting to restore the point difference on `line.coupon_id` after an update, it writes to an empty record. Solution -------- Store both coupons & their used points before write. After write, restore the previous points to the previous coupon, and subtract the current point cost from the current coupon. This way, any combination of coupon/point changes should have the points updated as expected. opw-4910922 Forward-Port-Of: odoo/odoo#230907 Forward-Port-Of: odoo/odoo#222054
User forms now handle cases where login and email differ more safely, especially when the HR app is installed on databases created during a recent transition. The update prevents setup errors, keeps email/login fields aligned, and adjusts the user image area so the form remains readable.
Original PR description
[1] adds back the login button on the user form when login and email are different. However as the override in hr is based on the new base view, this causes issues for people installing hr if they created their database before that commit was live. The login can be moved inside the email div and simply duplicated so that the hr module doesn't need to know about the new div. Although it may cause the field to appear twice on databases created the week this commit was live, it's a lesser issue than throwing a traceback. Icon margins are also tweaked to be consistent accross base and the hr override task-5130854 [1]: https://github.com/odoo/odoo/commit/db3dee12d7c17ad485800d000ec4cdd87fcfd18b
This fix makes all fields and action buttons in the appraisal skills list accessible again on mobile devices. Employees and managers can now scroll horizontally to view justification details and add or remove skill entries as intended.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 Forward-Port-Of: odoo/enterprise#96579 Forward-Port-Of: odoo/enterprise#91882
Location barcode images are now hidden when the stored barcode contains characters that cannot be displayed in the required format. This prevents upgrade failures for customers with unsupported barcode values while keeping valid barcodes visible as before.
Original PR description
A new field `barcode_img` was added odoo/enterprise@53d008e9ce11bbf870e5d2f248fd591fa679be0e to display location barcodes in the form view. It uses the `barcode` field of the location, but some clients have values with unsupported characters (e.g., `Ž`, `بيع`) that cannot be encoded in Code128. This caused upgrade failures as such barcodes could not be rendered. Now, Don't show barcode in the form view if it fails to render. opw-5129150
Video call links for appointments now use the correct website address when multiple company websites are configured. This prevents customers from receiving links with the wrong domain, improving reliability for businesses running appointments across different websites.
Original PR description
**Steps to reproduce:** - Create 2 companies - Create a website for each company - Set a custom website domain on the second one - Create appointement type for each website - Create an appointement on both websites - The link created for the video call has the wrong base for one of them **Issue:** Appointment `get_base_url` finds its base_url without considering the current website. **Fix:** Compute the base_url according to the appointement type to ensure the current website is taken into account. opw-4880715 Forward-Port-Of: odoo/enterprise#96826 Forward-Port-Of: odoo/enterprise#92734
Maintenance equipment pages now open reliably even when a repaired request has had its close date or request date manually cleared. This prevents customized or manually adjusted records from blocking users while still keeping repair metrics usable.
Original PR description
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them…
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them from opening equipment views that displayed fields that depended on it. Steps to reproduce: - Create new maintenance request for an equipment - Put maintenance request into a `maintenance.stage` where `done=True` (e.g. "Repaired") - Force `close_date` to not be `readonly` in form view + set it to `False` - Try to open the assigned equipment's form view Expected result: Form view opens without issue Actual result: `unsupported operand type(s) for -: 'bool' and 'datetime.date'` Issue was due to `mttr` calculation in `_compute_maintenance_request` not expecting `close_date` to be `False`. Since we want the request to still be considered for the rest of the compute, we count its "Time to Repair" as 0 in this case since we cannot use infinity in this case. Additionally, we also gracefully fail in the same way in case `request_date` is also forced to be `False` since it is not a mandatory field and can cause the same issue. 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#230942 Forward-Port-Of: odoo/odoo#230821
The appraisal skills list now allows horizontal scrolling on mobile, so users can access the justification field and add or remove buttons. This restores important appraisal editing actions for employees and managers using smaller screens.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230430 Forward-Port-Of: odoo/odoo#222161
The color picker now remembers where users last chose a color and opens that same tab the next time. This avoids extra clicks when editing website snippets, text colors, backgrounds, or gradients, making page customization smoother.
Original PR description
*web, website Before this commit, `BuilderColorPicker` had no memory of the last used tab and always opened on the first tab, regardless of whether the user had previously selected a color. After this commit, if the user has done a selection, the color picker opens on the tab of that selection. How to reproduce the problem: 1. Drop a new snippet, e.g. `s_text_block`, 2. Click on the snippet, then open the "Background" color picker 3. Pick a custom color or a gradient 4. If the color picker is stil open, press ESC 5. Open the color picker again 6. PROBLEM: the color picker is opened on the "theme" tab task-4367641 Forward-Port-Of: odoo/odoo#227197
Batch transfer confirmation now preserves the barcode settings needed to read location barcodes correctly. This prevents scans such as WH-Stock from being split into individual characters, allowing warehouse staff to continue batch picking without scan failures.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
7 changes
Resolved issues and error corrections
Invoice PDFs using the Boxed document layout now show the total amount section in the correct position. This keeps invoice reports visually consistent and professional across layouts.
Original PR description
**Steps to reproduce:** 1. Install Accounting module. 2. Change document layout to `Boxed` from Settings. 3. Print any invoice → notice that `total section` is shifted downward compared to other PDF layouts. **Issue:** <img width="772" height="242" alt="image" src="https://github.com/user-attachments/assets/d4c2aab8-11c1-4584-b544-0fcc7071a06a" /> - The amount `total section` in the invoice PDF is not aligned properly due to extra margin. **Solution:** - Remove the unnecessary margin to ensure the total section is aligned correctly across all layouts. **After Solution:** <img width="777" height="185" alt="image" src="https://github.com/user-attachments/assets/c9cd1060-f210-4154-afc9-22d7d6a9207f" /> **opw - 4911228**
This fix prevents GST return setup from failing when a multi-company tax unit's main company has no purchase journal configured. The system now looks across all companies in the tax unit to find a valid purchase journal, improving reliability for Indian GST reporting.
Original PR description
Before this PR: - The system searched for a purchase journal only in `company_id`. - In a tax unit with multiple companies, if the main company had no purchase journal configured, record creation failed with a 'NOT NULL constraint violated' error. After this PR: - The journal search now checks all companies in `company_ids` (or falls back to `company_id`), - allowing the system to find a valid purchase journal across the tax unit. OPW: 5159518 Forward-Port-Of: odoo/enterprise#96838
Document upload request emails now greet the person being asked to provide the document, instead of showing the sender or document owner's name. Invitation and reminder emails are also sent in the recipient's language, making requests clearer and more professional for users.
Original PR description
Currently, the email template inviting a user to upload a document displays the document owner's name in the greeting instead of the requestee's. This commit updates the template to display the correct name. Steps to reproduce: 1. Log in as Mitchell Admin 2. Go in the Document app 3. Click on the New > Request 4. Enter a document name and select Joel Willis as requestee 5. Send the request by clicking on the "Request" button => The invitation email is correctly sent to Joel Willis but it says "Hello Mitchell Admin" instead of "Hello Joel Willis" Additionally, this PR ensures that the reminders and the invitation emails are sent in the requestee's language rather than the sender's. Task-5130591
The working schedule calendar now keeps the hours-per-week value on one line. This small visual fix makes employee schedule information easier to read and avoids awkward line breaks.
Original PR description
Changed the style of hours/week in working schedule calendar so it doesn't appear on 2 lines Forward-Port-Of: odoo/enterprise#91993
This change prevents an uninstall process from failing when worksheet-related database fields have already been removed. It helps avoid incomplete module removals that could cause problems when reinstalling related apps later.
Original PR description
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks…
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks when uninstalling module `worksheet`:
```
ir.model.data._module_data_uninstall():
... records are deleted ...
ir.model.fields.unlink():
drop column of corresponding fields
delete ir.model.field records
ir.model.unlink():
drop table of corresponding models
ir.model._unlink_if_uninstalling():
self.env['worksheet.template'].search([('model_id', ...)]).unlink()
delete ir.model records
```
The call to `ir.model.unlink()` crashes when searching for worksheet templates, since column `model_id` has been dropped already. This makes the transaction fail, and it is rolled back to a savepoint just before the call to `ir.model.unlink()`. In other words, the uninstallation manages to drop most of the columns that must go, but fails to drop all the tables that must go. And the uninstallation proceeds anyway...
Now consider uninstalling module `resource`. That module defines model `resource.calendar` with required field `name`, and also defines a record in that model (a default calendar). When the module is uninstalled, module `worksheet` is also uninstalled (because it depends on `resource`), and so the situation above happens. Consequently, most of the columns of table `resource_calendar` are dropped, but the table is not. If we reinstall module `resource` after that, the ORM re-creates column `name` (which is `NULL` on the default calendar at least), but fails to add the `NOT NULL` constraint on that column.
The fix consists in avoiding the `search()` above in the ondelete method if the column `model_id` does not exist anymore.This update fixes payroll-related company filtering so it uses the country set on the company’s linked partner record. This helps Swiss and general payroll processes find the right companies reliably, avoiding issues caused by a non-searchable company country field.
Original PR description
As the country_id field on the company is computed and not searcheable, this commit adapts the domain to search for the country of the associated partner. task-5096037
Spanish Veri*Factu invoices for customers outside Spain now select the correct export regime key instead of the general regime. This helps businesses submit more accurate e-invoicing data and avoid manual corrections for export invoices.
Original PR description
### Steps to reproduce: - Install l10n_es_edi_verifactu and switch too Spanish company - Create an invoice for a partner outside Spain (or with the tax "0% EX G") - Check the "Veri*Factu Regime Key" under the page "Veri*Factu" - It should be "Export" (02) but it's "General Regime Operation" (01) ### Cause: `_l10n_es_edi_verifactu_get_suggested_clave_regimen()` is called on the tax "0% EX G". The line ```taxes.filtered(lambda tax: (tax.l10n_es_type not in main_tax_types or tax._l10n_es_edi_verifactu_get_applicability() != forced_tax_applicability))``` doesn't do what the comment says: remove the main taxes with a different applicability. ### Solution: Change the `!=` to `==` so that the line does the same thing as the comment. opw-5071665 Forward-Port-Of: odoo/odoo#230823
7 changes
New functionality added to Odoo
Odoo now includes the latest unit of measure codes introduced by the Egyptian Tax Authority. This helps Egyptian electronic invoicing users select compliant default unit mappings and keep invoices aligned with current ETA requirements.
Original PR description
The Egyption Tax authority (ETA) introduced new uom unit types The unit types can be viewed at https://sdk.invoicing.eta.gov.eg/codes/unit-types/ This commit updates odoo's standard offering to match ETA and adds additional default mapped values for l10n_eg_unit_code_id field 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
Resolved issues and error corrections
Changing an activity type in the scheduler now correctly updates or clears the summary and note based on the newly selected type. This prevents users from accidentally keeping outdated instructions when switching to an activity type with no default text.
Original PR description
Steps to reproduce: -------------------------- 1. Install Discuss Module 2. Create two activity types: one with a default summary and default note, and another with both fields empty. 3. Go to any…
Steps to reproduce: -------------------------- 1. Install Discuss Module 2. Create two activity types: one with a default summary and default note, and another with both fields empty. 3. Go to any user's partner record and click on Activities from Chatter 4. Select the activity type with the default summary and note. 5. Now change it to the activity type with no summary and note. Observation: -------------------------- The scheduler still shows the previous summary and note after changing to an activity type without defaults. Issue: -------------------------- The compute methods only update the summary and note if the new activity type has them. As a result, fields are not cleared when the new type has empty values https://github.com/odoo/odoo/blob/b2c1af2e60968ee745e0a1238602aafe12f486b0/addons/mail/wizard/mail_activity_schedule.py#L167-L177 Solution: -------------------------- Remove the condition that blocks updating the summary and note. Now, the scheduler updates correctly even when the new activity type has no summary or note. opw-5106771
The HR organization chart now avoids an error that could occur when loading employees with many levels of subordinates. This makes the org chart more reliable for companies with deep management structures.
Original PR description
This commit fixes a recursion error that occurs in `_get_subordinates`. An iterative approach is used instead of the current recursive implementation. task-5118697 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Subscriptions MRR Breakdown report now ignores archived companies when preparing report data. This prevents access errors for users working in databases where the original company was archived and another active company is in use.
Original PR description
Step to reproduce: - Start database without demo data and install Subscriptions - Create a new Company and archive the first Company in the Database - Set a currency rate on a currency (i.e. Euro),…
Step to reproduce: - Start database without demo data and install Subscriptions - Create a new Company and archive the first Company in the Database - Set a currency rate on a currency (i.e. Euro), then set that currency as the Main Currency of the new Company. - Then, set a currency rate on the previous Main Currency i.e USD. - Create a Subscription Sales Order and confirm it. - Open the MRR Breakdown report. - Click into the data of the report. Observation: An error message will occur appear (Access Error) Issue: - when building the query, it also fetches the archived company, due to `active_test` context applied from [fetch()](https://github.com/odoo/odoo/blob/754599a7720ee179fc5304b9613df9c177e4b231/odoo/models.py#L3858), and hence wrong query is build which fetches no data, leading to sort of access error as this [condition](https://github.com/odoo/odoo/blob/754599a7720ee179fc5304b9613df9c177e4b231/odoo/models.py#L3876) matches. Fix: - we explicitly search for active companies opw-5090463
This fix adds the missing sample blog data needed for an automated website blog tour to run reliably. It prevents test failures in environments without preloaded demo data, improving confidence in blog feature validation without changing customer-facing behavior.
Original PR description
With PR [1], the blog_tags_with_date tour was introduced, but the required demo data were missing, causing the tour to fail when executed in an environment without demo data. This commit adds the necessary demo records to ensure the tour runs successfully even when no demo data are present. [1]: https://github.com/odoo/odoo/pull/225845 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
Swiss payroll users can now access all required backend configuration fields directly from the salary rule screen. This helps payroll teams configure wage types more completely and reduces the need for technical backend access.
Original PR description
task-4954650
Restricted website editors can now update pages even after an administrator adds an embedded video. The change keeps videos visible to visitors while storing them in a way that remains compatible with content safety rules, reducing editing interruptions for business teams.
Original PR description
Steps to reproduce the current behaviour: - Update the DEMO user to be a website "restricted editor" and sales "admin" who cannot bypass HTML field sanitization. - As ADMIN, add a YouTube video to a…
Steps to reproduce the current behaviour: - Update the DEMO user to be a website "restricted editor" and sales "admin" who cannot bypass HTML field sanitization. - As ADMIN, add a YouTube video to a product page > Save. - As DEMO, try to update the content on the product page > You cannot (a dialog informs you that you cannot edit the content because an admin edited it previously). Explanation: Starting from [1], an HTML field can be flagged as `sanitize_overridable` which allowed users with the `base.group_sanitize_override` group to skip the HTML field sanitize process. If such users added some content that is not considered "sanitize friendly" (e.g. YouTube iframe), a restricted user won't be allowed to add content in the fields, since the sanitizer will remove the original content from the DOM. For this case, the code from [2] added an implementation to consider the field as none editable and warn the user once he tries to update it. Implementation: The goal of this commit it to fix the current limitation for video upload that currently prevents non admin users to edit a website record once an admin adds a video on it... The idea of the fix is the following: - We already have a technical fallback when uploading a video to save the iframe `src` to an attribute: `data-oe-expression`. - The public widget is now destroying the video iframes so they are never saved in the DOM. - A non-lazy code will build the iframes immediately on page load. - The public widget can always create the iframes if they are not already created (for compatibility). [1]: https://github.com/odoo/odoo/commit/cf844e34dd0ce4830eb99fd0fa5b6b9cb58c867c [2]: https://github.com/odoo/odoo/commit/cb80c15d3db49ede3c93171abcaa9064b88822c6 task-3757205