Daily updates from Odoo
Monday, October 13, 2025
25 changes · master
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