Daily updates from Odoo
Wednesday, November 19, 2025
214 changes
12 changes
Resolved issues and error corrections
This change corrects how website page links are saved so they stay readable and open properly across browsers. It prevents valid page URLs from turning into 404 errors when users type them manually or copy and paste them, especially for characters like Korean text.
Original PR description
Scenario: - create a page with url "가" (\N{HANGUL SYLLABLE GA}) then in safari: copy the url to open it in a new tab => a 404 error is shown in all browser: go to /가 writing it manually => a 404…
Scenario:
- create a page with url "가" (\N{HANGUL SYLLABLE GA})
then in safari: copy the url to open it in a new tab => a 404 error is shown
in all browser: go to /가 writing it manually => a 404 error is shown
Cause:
We decompose the unicode combination to remove diacritics, but never
recompose them, so we save the slug
\N{HANGUL CHOSEONG KIYEOK}\N{HANGUL JUNGSEONG A} (NFD normalization)
instead of \N{HANGUL SYLLABLE GA} (NFC normalization). Those appear
exactly the same, but when typing you would usually use the NFC one.
Comparing other software, they usually convert NFD to NFC but not the
other way.
When you use the address bar in safari, the URL is normalized with NFC
so you can't type or copy paste a NFKD path to get to it (and can only
get to it by link).
But the issue still exists for other browser where you will usually
manually type NFC and not NFKD.
This is not reproduced, but this could also have effect with search motor
that would normalize link content.
Fix:
When creating slug, normalize to NFC after the removal of diacritics.
opw-5184532
__pr note:__
the original ticket also reported about removal of diacritical mark in Vietnamese and Japanese, but this seems a more of a feature for master change since we have had "éléphant" becomes "elephant" since forever.
other services that allow unicode in path (such as wordpress, wix) seems to just keep the diacritics and normalize to NFC even if the input was in NFD.
for NFD / NFC explanation: https://docs.python.org/3/library/unicodedata.html#unicodedata.normalize
Forward-Port-Of: odoo/odoo#234416This change fixes a problem where attaching a file could fail after users interacted with elements inside modern, embedded UI components. It makes file uploads work reliably in those cases, reducing frustrating errors for testers and users.
Original PR description
Before this commit, using 'setInputFile' after interacting with an element contained in any shadow root would not work ("no input has been interacted with" error).
This commit allows the listeners responsible for detecting clicks/focus on file inputs to handle the shadow root cases properly.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235961Fixes an issue where the “Update extra prices” action could disappear after a form was saved, even when other variant lines still needed updating. This ensures all relevant product variant prices stay in sync, reducing the risk of incorrect prices being added to sales orders.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update…
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update extra prices"; 5. add the updated variants to a sale order. Issue ----- Only the line on which "Update extra prices" was clicked has been updated, even though the button disappeared on all lines after clicking it. Cause ----- The `_compute_default_extra_price_changed` method only compares the `default_extra_price` of the current record to its `_origin` value. Consequently, after saving the form, it will return `False`, even though only one attribute has been updated. Solution -------- Aside from checking whether the value changed on the form, also check whether any product template attribute value has a `price_extra` that's different from the product attribute value's `default_extra_price`. This way, clicking on "Update extra prices" once won't make the other update buttons disappear. opw-5240236 Forward-Port-Of: odoo/odoo#235088
The activity list now keeps paging correctly when some activities are hidden from a user by access rules. This prevents users from getting stuck on the first page and makes sure they can browse all activities they are allowed to see.
Original PR description
**Steps to reproduce:** - Create some activities which should not be accessible to a specific user (according to the `_search` filtering of `mail.activity`) - Go to Activity Menu > View all…
**Steps to reproduce:** - Create some activities which should not be accessible to a specific user (according to the `_search` filtering of `mail.activity`) - Go to Activity Menu > View all activities as the given user - Ensure that the limit (default: 80) is lower than the total number of activities which should be returned and that the new activities are in the returned elements - On `web_search_read` some records are removed by the `_search` override - The pagination navigation buttons are disabled as the returned number of records is lower than the limit - This means that some activities are not accessible to the user (everything above the given limit) **Issue:** The issue comes from the `_search` override which checks the records available to the user. As it's done after fetching with the limit, the resulting number of records can be lower than expected and this breaks the `_format_web_search_read_results` which considers that we have all the possible records and doesn't try to fetch the total count of records. **Fix:** The main issue can't be directly fixed without modifying the way the access are checked in the `_search` override. This could be mitigated by changing the search limit, making the search as superuser, or adding specific filtering but each has its own limitations. Adding `force_search_count` should allow the user to navigate between pages anyway and see all the available activities. But the number displayed in the pagination will often be incorrect for the current and total count. (e.g. we can have 75 records but 1-80/150 is displayed out of 140 actually readable records) opw-5046389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233585
Users with billing access can now revoke SEPA Direct Debit mandates even if the mandate was used for an online customer payment. The linked saved payment methods are deactivated automatically, avoiding access errors for non-admin users.
Original PR description
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** -…
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** - Enable SEPA Direct Debit payment provider in Test Mode - Create a mandate for a customer w/ valid IBAN - Create an invoice for that customer and post it - Action > Generate a Payment Link, open this in an incognito window - Pay using SEPA Direct Debit - Call `_set_done()` on the payment.transaction - Try to revoke the mandate as a non-admin with "Accounting / Billing" -> Access Error, can't modify payment.token **Cause:** - When SEPA Mandate is revoked, we check for all associated payment tokens (saved payment methods from SEPA Direct Debit payment provider) and deactivate them. - The check in code isn't called with sudo, so it uses the current user access rights, but only admins can modify the payment tokens in any way. **Solution:** - Write to the `linked_tokens` with sudo so we can archive the tokens regardless of user access opw-5136221 Forward-Port-Of: odoo/enterprise#99592 Forward-Port-Of: odoo/enterprise#99232
This fix ensures dialogs opened from chat actions are displayed in front of the mobile chat window instead of being hidden behind it. As a result, users can see and use these dialogs immediately without having to minimize the chat window first.
Original PR description
**Purpose of this PR :** - Before this PR, dialogs triggered by message actions were rendered beneath the chat window in mobile view due to incorrect `z-index` hierarchy. This created a confusing UX where users had no visual feedback, only discovering the hidden dialog after minimizing the chat window. - This PR adjusts the `z-index` values to ensure dialogs are properly elevated above the chat window layer, restoring the expected stacking context and enabling direct interaction with modal dialogs. **Current behavior before PR:** [before_z.webm](https://github.com/user-attachments/assets/8063633f-6de7-4874-9884-963f4d223587) **Desired behavior after PR is merged:** [after_z.webm](https://github.com/user-attachments/assets/5674a953-8308-4469-907d-311a0d5a3f94) Backport of https://github.com/odoo/odoo/pull/235852 task-[5208322](https://www.odoo.com/odoo/project/1519/tasks/5208322) Forward-Port-Of: odoo/odoo#234540
This change prevents an error that could happen when a sales user quickly adds a product from the catalog and immediately removes it. If no order line has been created yet, the system now falls back to the sales price list instead of crashing, making the sales order flow more reliable.
Original PR description
Currently, an error occurs when the user immediately removes a catalog product after adding it. Steps to Reproduce ([Video](https://drive.google.com/file/d/12hOavt1zCa6hbG0EWHsIDGxfgVkxJmLW/view)): -…
Currently, an error occurs when the user immediately removes a catalog product after adding it. Steps to Reproduce ([Video](https://drive.google.com/file/d/12hOavt1zCa6hbG0EWHsIDGxfgVkxJmLW/view)): - Install the `sale_management` module. - Go to `Sales Orders` and create a new `sale order`. - In the order line, click on the `Catalog` button. - `Add` a product and then immediately `remove` it. `ValueError: Expected singleton: sale.order.line()` After [this commit], when the user clicks the Remove button immediately after clicking the Add button (within 500 ms). In this case, the system proceeds with the last request due to the useDebounced delay [1], which removes the product. However, since there is no order line yet for that product [2] and the quantity is 0, the order line [3] is not created. When it attempts to retrieve the discounted price, it raises the error [4]. This commit ensures that if no order line exists, the product's price is returned according to the sale order's pricelist. [this commit]: https://github.com/odoo/odoo/pull/233098/commits/697c559791fdf00b5602b9459bbdf21f392757d8 [1]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/product/static/src/product_catalog/kanban_record.js#L17-L19 [2]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order.py#L2202 [3]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order.py#L2218-L2219 [4]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order_line.py#L1602-L1603 sentry-7019831319 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235470
This update corrects how journal items are handled on accounting entries so the system uses the right data behind the scenes. It prevents existing lines from disappearing and ensures debit and credit amounts are computed correctly when new lines are added.
Original PR description
The [commit](https://github.com/odoo/odoo/commit/6ed1e43b3f7d53c6a45fe24a1c68f8386e6adf8e) introduced the `journal_line_ids` field on `account.move` to hide sections and notes from the Journal Items tab. However, the context for the Journal Items was not updated to reference this new field. It still referenced the previous `line_ids` field, which caused inconsistencies when the `onchange` method was triggered. Specifically, this led to: - The existing lines being lost during the `onchange` computation. - Incorrect computation of the `debit` and `credit` fields when adding new lines, as the balance computation was prevented. This commit updates the context to use `journal_line_ids` correctly, resolving the inconsistencies and restoring proper balance computation. task-5241650 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When a customer pays for an order that includes a gift card, the system could fail with an error and not produce the gift card report. This fix restores the expected checkout flow so the report is generated and downloaded correctly after validation.
Original PR description
Current behavior: ----------------- A traceback occurs upon validation of an order that contains a giftcard. Steps to reproduce: ------------------- * Open shop * Add giftcard to the order * Go to pay the order * Select a payment method and validate > Observation: A traceback occurs, giftcard report not downloaded Why the fix: ------------ It seems like when this code was forwarded some uses this.env.services.report and some just this.report. https://github.com/odoo/odoo/commit/246515874e863b72626da11a4f5151599b0fa7b5 18.0 has already been changed to use this.env.services.reports and was not merged forward because 18.2 was already using this.env.services.reports. However we need to fix the version pat 18.2 using this.report. opw-5261898 Forward-Port-Of: odoo/odoo#236215
This update fixes an issue where the system could stop too early when several accounting entries were unbalanced. As a result, users now get a complete error message showing all affected entries, making it easier to identify and correct problems faster.
Original PR description
The commit 3467b5971423f70581c6be2caf7f8a8d86ee70f1 intended to improve the error message in `_check_balanced()` by tailoring it based on the number of affected entries. However, in the case of multiple affected entries, the error was raised after the first iteration, preventing the full list of unbalanced entries from being collected and displayed to the user. no-task --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236212
This fix removes an error that could block refusing a time-off allocation when a leave already existed in the same period. It ensures the allocation is assessed correctly, so users are not asked to delete the wrong leave before they can cancel the allocation.
Original PR description
## Issue: When you have an allocation and set a leave for that period, if you add a new allocation for that period and you validate it, it will be impossible to Refuse this allocation later A…
## Issue: When you have an allocation and set a leave for that period, if you add a new allocation for that period and you validate it, it will be impossible to Refuse this allocation later A UserError was raised asking to remove the leave even if it should be linked to the first allocation created ## Cause: The `action_refuse()` method for `hr.leave.allocation` uses the `virtual_leaves_taken` value inside the `_get_consumed_leaves()` function's result That parameter is calculated for the allocation as far as it state is `validate`, for all the leaves in that time interval, including previously created leaves The leaves will be allocated to the last allocation created, so the last one can't be removed later As a result, the allocation is considered as already used by these pre-existing leaves, even if the leave can still be modified to return to the state prior to the allocation's validation ## Steps to reproduce: - Create an initial Allocation (that should end after the next created Allocation) - Create a Leave from 22/12/2025 to 31/12/2025 - Create an Allocation including the leave period (01/12/2025 to 31/12/2025) - Validate, then Refuse opw-4900686 Forward-Port-Of: odoo/odoo#235711 Forward-Port-Of: odoo/odoo#222171
This change restores the expected behavior of the VoIP keypad backspace key when highlighted text starts at the beginning of the field. It prevents a regression where deleting selected characters could stop working, while still keeping the input safe when the cursor is in sensitive positions.
Original PR description
This commit fixes a regression introduced in commit [1] prevented deleting when a selection began at index 0; extend the guard so the numpad (keypad) backspace still removes the highlighted characters while keeping the cursor-safety logic. [1]: https://github.com/odoo/enterprise/commit/73b01fa5e1f56d4ab71d67760b15942fb2fa0e31 task-5217676 Forward-Port-Of: odoo/enterprise#99655 Forward-Port-Of: odoo/enterprise#99358
6 changes
Resolved issues and error corrections
This change removes a unit test that depended on a different module setup and on enterprise-only fields. Removing it prevents automated build checks from failing and keeps the codebase aligned with the correct module boundaries until a proper replacement is added.
Original PR description
The unit test `test_can_reset_deferred_invoice()` has several issues. 1. It should be in the `account_audit_trail` module, as the test requires this module. [Unit test documentation: modules](https://www.odoo.com/documentation/19.0/developer/tutorials/unit_tests.html#modules). 2. The test references fields from the Enterprise module `account_accountant`, `account.move.line.deferred_start_date` and `account.move.line.deferred_end_date`. This causes build tests to fail. As such, the test should be removed now and replaced later if necessary. Fixes [PR 235223](https://github.com/odoo/odoo/pull/235223) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235813
This update prevents an error that could happen when a salesperson quickly adds a product from the catalog and immediately removes it. If no order line exists yet, the system now falls back to the sale order’s pricelist instead of failing, keeping the sales flow smooth.
Original PR description
Currently, an error occurs when the user immediately removes a catalog product after adding it. Steps to Reproduce ([Video](https://drive.google.com/file/d/12hOavt1zCa6hbG0EWHsIDGxfgVkxJmLW/view)): -…
Currently, an error occurs when the user immediately removes a catalog product after adding it. Steps to Reproduce ([Video](https://drive.google.com/file/d/12hOavt1zCa6hbG0EWHsIDGxfgVkxJmLW/view)): - Install the `sale_management` module. - Go to `Sales Orders` and create a new `sale order`. - In the order line, click on the `Catalog` button. - `Add` a product and then immediately `remove` it. `ValueError: Expected singleton: sale.order.line()` After [this commit], when the user clicks the Remove button immediately after clicking the Add button (within 500 ms). In this case, the system proceeds with the last request due to the useDebounced delay [1], which removes the product. However, since there is no order line yet for that product [2] and the quantity is 0, the order line [3] is not created. When it attempts to retrieve the discounted price, it raises the error [4]. This commit ensures that if no order line exists, the product's price is returned according to the sale order's pricelist. [this commit]: https://github.com/odoo/odoo/pull/233098/commits/697c559791fdf00b5602b9459bbdf21f392757d8 [1]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/product/static/src/product_catalog/kanban_record.js#L17-L19 [2]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order.py#L2202 [3]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order.py#L2218-L2219 [4]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order_line.py#L1602-L1603 sentry-7019831319 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235470
When a product was edited and saved in Point of Sale, its reference could briefly appear before the product name. This fix keeps the display consistent so staff see the expected product name instead of the reference code.
Original PR description
In PoS, when editing and saving a product’s information, there was a bug where the product reference was shown before its name. Steps to reproduce: ------------------- * Add a reference to a product available in PoS * Open PoS * Click on the 'i' on the top right of that product * Click on Edit * Click on Save (no need to do any modification) > Observation: The reference appears before the name. Refreshing the page removes, as it triggers a new read. Why the fix: ------------ Reference are never shown in pos thank to this context key `display_default_code: false` opw-5001355 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233812 Forward-Port-Of: odoo/odoo#222640
This update improves the message shown when accounting entries are not balanced. Instead of stopping after the first issue, it now collects all affected entries so users can see the full list of problems at once and fix them more efficiently.
Original PR description
The commit 3467b5971423f70581c6be2caf7f8a8d86ee70f1 intended to improve the error message in `_check_balanced()` by tailoring it based on the number of affected entries. However, in the case of multiple affected entries, the error was raised after the first iteration, preventing the full list of unbalanced entries from being collected and displayed to the user. no-task --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236212
The import screen now correctly shows formatting options for CSV files even when the file name ends with .CSV in uppercase. This makes the import experience more consistent and avoids confusion for users importing data from different sources.
Original PR description
Before this fix, the import side panel displayed the formatting options only when the uploaded file had a lowercase .csv extension. Files with an uppercase .CSV extension could still be imported but did not show the format selection section, leading to inconsistent behavior. This commit updates the condition to perform a case-insensitive comparison on the file extension. Task-5145031 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236020 Forward-Port-Of: odoo/odoo#235061
This fix lets users refuse a validated leave allocation even if leave records already exist for the same period. It prevents a false error that incorrectly told users to remove the leave first, even when that leave should belong to an earlier allocation.
Original PR description
## Issue: When you have an allocation and set a leave for that period, if you add a new allocation for that period and you validate it, it will be impossible to Refuse this allocation later A…
## Issue: When you have an allocation and set a leave for that period, if you add a new allocation for that period and you validate it, it will be impossible to Refuse this allocation later A UserError was raised asking to remove the leave even if it should be linked to the first allocation created ## Cause: The `action_refuse()` method for `hr.leave.allocation` uses the `virtual_leaves_taken` value inside the `_get_consumed_leaves()` function's result That parameter is calculated for the allocation as far as it state is `validate`, for all the leaves in that time interval, including previously created leaves The leaves will be allocated to the last allocation created, so the last one can't be removed later As a result, the allocation is considered as already used by these pre-existing leaves, even if the leave can still be modified to return to the state prior to the allocation's validation ## Steps to reproduce: - Create an initial Allocation (that should end after the next created Allocation) - Create a Leave from 22/12/2025 to 31/12/2025 - Create an Allocation including the leave period (01/12/2025 to 31/12/2025) - Validate, then Refuse opw-4900686 Forward-Port-Of: odoo/odoo#235711 Forward-Port-Of: odoo/odoo#222171
1 change
Resolved issues and error corrections
This change stops manufacturing quality checks from being created for component items when they should only apply to the finished product. It reduces false alerts during production and makes quality control behave as expected for manufacturing orders.
Original PR description
### State of the art: Control point for the manufacturing operation type are not expected to create QC when they refer to components. ### Steps to reproduce: - Create a BOM for a final product FP: -…
### State of the art:
Control point for the manufacturing operation type are not expected to create QC when they refer to components.
### Steps to reproduce:
- Create a BOM for a final product FP:
- 1 X COMP (consumable)
- Create a Quality Control Point:
- Control: Quanity
- Operations: Manufacturing
- Product: COMP
- Create and confirm an MO for 1 unit of FP
#### > A QC is created for the component
### Cause of the issue:
Quantity quality checks related to MOs are expected to be created by `_create_quality_checks_for_mo`, which ensures that only moves referring to the production are considered:
https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/quality_mrp/models/stock_move.py#L23-L29
However, each time a `stock.move.line` is created, it triggers the related "quantity" control points if it is not filtered out of the applicable lines:
https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/quality_control/models/stock_move_line.py#L28-L35
The issue is that move lines related to `move_raw_ids` are always considered applicable:
https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/quality_mrp/models/stock_move_line.py#L31-L34
and that the `_create_check` triggers "quantity" control points that directly refer to the `product_id` of the move line:
https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/quality_control/models/stock_move_line.py#L79-L88
Note, however, that `_create_check` ignores control points of move lines related to a raw move if they do not refer to any product_ids, due to `_get_quality_points_all_products` (which is only called to find control points without a set `product_ids`):
https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/quality_mrp/models/stock_move_line.py#L20-L24
This explains why the test `test_04_quality_check_on_quantity` did not trigger the creation of quality checks for components.
### opw-5137594
Forward-Port-Of: odoo/enterprise#9721737 changes
Resolved issues and error corrections
Rental product availability now stays accurate when only part of a rental order has been returned. This prevents staff from seeing too many units as available and helps avoid overbooking rental inventory.
Original PR description
### Issue: Due to this bug, virtual available is not calculated correctly when there are rental orders with some returned lines. #### To reproduce: 1- Create a storable rental product with 10 units in stock. 2- Enable the 'Rental Transfer' setting. 3- Create a rental order with two lines: - line 1: 4 units - line 2: 1 unit 4- Confirm and pick up order lines 5- Return the line with 1 unit 6- Create another order: it must show 6 available but 7 is shown #### Cause: This is caused due to filter on lines in `_get_virtual_unavailable_qty_in_rent` which filters lines with `order_id.rental_status`. However this filter misses the lines which have different status than the `order_id`. In #88689, `rental_status` field is added to `sale_order_line`. Using the `sale_order_line.rental_status`, we can ensure only line with status in `return` and `pickup` are considered. opw-5185084 Forward-Port-Of: odoo/enterprise#98689
When the Belgian POS cannot reach the Blackbox due to a timeout, it now shows a more accurate error instead of saying the fiscal module is missing. This helps cashiers and support teams understand the real issue faster and avoid unnecessary troubleshooting.
Original PR description
Before this commit, in the case when there is a timeout communicating with the Blackbox in the POS, an incorrect error message was shown stating that "The IoT Box is connected but the Fiscal Data Module isn't". This message should only be shown when we receive a reply from the IoT box, but it tells us it cannot find the Blackbox. <img width="695" height="240" alt="image" src="https://github.com/user-attachments/assets/ec011f4a-42dd-4ffd-8741-350032897471" /> Forward-Port-Of: odoo/enterprise#99652
German companies with a dot in their name can now export DATEV reports without encountering an error. This prevents export failures in the General Ledger and keeps accounting reporting workflows running smoothly.
Original PR description
Currently companies with a dot ('.') in the name cannot export the DATEV report due to a traceback.
Steps to reproduce:
- Select a German (DE) Company having a dot in the name.
- Open Accounting / Reporting / Ledgers / General Ledger
- Click cog > Datev DATA (zip)
Issue:
A Traceback will occur
`Error "ValueError: too many values to unpack (expected 2)"`
This occurs because the system separate the filename from the extension without halting to the first `.`, leading to the error.
opw-5232073
Forward-Port-Of: odoo/enterprise#99578Recruitment administrators without employee access could hit an access error when sending referral campaigns. This fix lets the intended recruiting users send referral campaigns successfully, reducing disruption in hiring workflows.
Original PR description
STEP TO REPRODUCE:
------------------
1- Give to Marc Demo the right : Recruitment / Administrator (be sure he doesn't have any right on Employees)
2- Log as Marc Demo
3- Go to Recruitment
4- Click on the three dots in kanban card
5- Click on Referral Campaign
6- Click on Send
You will have an access error
This user (with these groups) should be able to send a referral campaign
task-5082344
Forward-Port-Of: odoo/enterprise#99184
Forward-Port-Of: odoo/enterprise#96746Spreadsheet sharing now avoids showing a warning that cannot lead to any action when edit access is blocked for external users. This makes the sharing dialog less confusing by presenting only the relevant message.
Original PR description
Bug === 1. Create a spreadsheet 2. Add a partner as viewer 3. Set access vial link to edit => 2 warning are displayed (that the right will be extended, and that we can not share spreadsheet in edit mode to non-internal users). The first warning make no sens, because we can not save the modal. Task-5169034 Forward-Port-Of: odoo/enterprise#97857
FEC imports now avoid keeping temporary matching numbers that could prevent some journal items from being automatically reconciled after posting. This helps ensure imported French accounting files reconcile consistently across accounts, reducing manual cleanup for accounting teams.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit provides a test to reproduce this issue. opw-5086823 Forward-Port-Of: odoo/enterprise#98855
This update prevents an intermittent failure in an automated manufacturing work order test by avoiding a timing issue in the component selection dialog. It also ensures the intended product appears first, making the test more stable without changing business workflows.
Original PR description
The search in the "Add Component" dialog caused a re-render race, making the tour ``test_add_component_from_shop_foor_in_multi_step_manufacturing`` fail intermittently. This fix removes the search steps and marks the “Courage” product as favorite so it appears first in the catalog. runbot-227694 Forward-Port-Of: odoo/enterprise#92403
VoIP now avoids starting a new connection registration when a user naturally leaves or closes the page. This prevents conflicting requests that could trigger errors during page unload, improving call service stability without changing user workflows.
Original PR description
On page unload, two conflicting things happen: - A REGISTER request with expires=0 is sent to invalidate the registration - The WebSocket disconnects, triggering the reconnection mechanism that attempts to reissue a registration These two concurrent and conflicting REGISTER requests result in the following error: > RequestPendingError: REGISTER request already in progress, waiting for final response This commit prevents the reconnection mechanism from occurring in the event of a "natural" disconnection, such as one triggered by a page unload. This way, the two conflicting REGISTER requests aren't sent on page unload. [Task-5261940](https://www.odoo.com/odoo/project/5778/tasks/5261940) Forward-Port-Of: odoo/enterprise#99560 Forward-Port-Of: odoo/enterprise#99376
The report editor now keeps the user's cursor and selection in the right place after inserting an X2Many table in a new report. This prevents editing disruptions and lets users continue typing immediately after adding the table.
Original PR description
On a new report, add a X2Many table in a new Report. In many cases there will be some issues with the selection as, when inserting the Element via the command of the report Editor we explicitly focus the editable of the html_editor. We need the document inside the iframe to get the focus, because our flow implied to click on some popover bound to the main window. But focusing the editable element changed the selection. So, instead, we focus the iframe's inner window, and the selection stays at the right place, and the user can immediately interact with it (by continuing typing after the insertion) task-5159482 Forward-Port-Of: odoo/enterprise#99430 Forward-Port-Of: odoo/enterprise#97642
Attendance Officers without payroll permissions can now edit attendance records even when related work entries already exist. The system safely handles the required work entry regeneration in the background, preventing unnecessary access errors and keeping attendance management smooth.
Original PR description
Steps to reproduce: 1. Log in as an Attendance Officer without payroll rights. 2. Attempt to edit any attendance record. Cause: If work entries already exist for the attendance, Odoo tries to regenerate them an action requiring payroll permissions. Solution: Execute the work entry regeneration wizard with sudo to bypass the payroll access restriction. Task: 5265141 Forward-Port-Of: odoo/enterprise#99507
This change fixes a payroll configuration issue that caused automated build tests to fail for some country-specific payroll setups. The overtime attendance setting is now handled only by the module that provides it, improving reliability without changing day-to-day payroll workflows.
Original PR description
The issue occurs because the _get_whitelist_fields_from_template() method includes the overtime_from_attendance field, introduced in this https://github.com/odoo/enterprise/pull/92093. This field comes from the hr_work_entry_attendance module, which is not listed as a dependency in all payroll localisations. As a result, the field cannot be found during test execution. Solution: Remove the overtime_from_attendance field from all _get_whitelist_fields_from_template overrides in the localisation modules, and instead include this field by overriding the function in the hr_work_entry_attendance module. build error-243483 task-5169211 Forward-Port-Of: odoo/enterprise#97201
The French reporting EDI export form now shows formatted status and error messages instead of raw HTML text. This makes report results easier to read and helps users quickly identify errors highlighted in the interface.
Original PR description
Currently, the message field in the EDI export form displays raw HTML tags instead of properly formatted content, making it difficult for users to read the report status and error details. We now ensure that HTML is rendered. This allows the structured list of statuses and error details (with proper formatting and red color for errors) to display correctly in the UI Note: Wrap the computed message with Markup() during concatenation in _compute_message() to prevent the HTML from being escaped when combined with translated strings. Task-5113752
This update fixes an internal link from payslips so it opens the related employee record in the proper form view. Payroll users can navigate more reliably without being sent to the wrong screen or view.
Original PR description
The contract template form view is now written on the formview_action directly. This is a backport of https://github.com/odoo/enterprise/pull/97463 task-5082709 Forward-Port-Of: odoo/enterprise#99486
Vendor batch payments now use the correct outgoing payment numbering sequence instead of accidentally using the incoming payment sequence. This prevents confusing or incorrect batch names when validating supplier payment batches.
Original PR description
Currently when creating a vendor batch payment, the system may incorrectly use the inbound batch payment sequence to generate the batch name Steps to reproduce: - Create a Vendor payment. - Create a Vendor batch payment, add the payment, validate it. Issue: Name has been set using the incoming batch payment sequence This occurs because `batch_type` is set to readonly when a payment is added to the list. As result, the current batch type is never sent to the backend that will use the default 'inbound'. opw-5128426 Forward-Port-Of: odoo/enterprise#99570
Restaurant floor plans now receive website table booking notifications only when the booking uses the appointment type configured for that POS. If table booking is disabled or no appointment type is selected, irrelevant notifications are avoided, reducing confusion for staff.
Original PR description
Task: [#5005216](https://www.odoo.com/odoo/my-tasks/5005216) Enterprise v17.0: [#93714](https://github.com/odoo/enterprise/pull/93714) --- **Before:** If no appointment type is specified in the POS config and a table is booked via the website, the floor plan is notified of a new booking because the resource used is one of the POS config resources. However, if the page is refreshed, the booking disappears since no appointment type is defined in the POS config **After:** The floor plan is notified of a new booking only if the appointment type of the booking matches the one specified in the POS config. If no appointment type is set in the POS config, no booking notifications are sent. Additionally, when the "Table Booking" field is unchecked in the POS config, the appointment type is automatically unset. Forward-Port-Of: odoo/enterprise#98887 Forward-Port-Of: odoo/enterprise#93636
Purchase orders no longer incorrectly link to budget lines from other companies when using shared analytic accounts. This prevents users working in one company from seeing access errors caused by another company's budget data, making multi-company purchasing smoother.
Original PR description
Steps to reproduce: - Create an analytic account [ACCOUNT] not restricted to any company - Create an analytical distribution model applying [ACCOUNT] to [PRODUCT] not restricted to any company - Create a budget in company [COMP A] using analytic account [ACCOUNT] - Create a budget in company [COMP B] using analytic account [ACCOUNT] - In company [COMP B], create a purchase order, add [PRODUCT] to a line Issue: Access Error is raised Analysis: Because we search with sudo company rules are bypassed and the system assign both budget lines to the order line (budget_line_ids). When we access the field, the system try to access the budget line of the other company, causing the error. As solution we revert https://github.com/odoo-dev/enterprise/commit/4941c1928c9a2bcb38af3cadf023f904c9fd9be0 removing the `sudo` on the search and we explicitly check if the user has read access on the budget analytic model opw-5056712 Forward-Port-Of: odoo/enterprise#98573
OSS sales returns will no longer be created when their eligibility conditions are not met. OSS import returns now use similar eligibility checks, reducing unnecessary reports and helping users avoid incorrect compliance paperwork.
Original PR description
The OSS Sales returns was generated even when its condition wasn't met since auto_generate was still at True. The OSS Imports didn't have any condition and has one which is similar to the OSS Sales. Forward-Port-Of: odoo/enterprise#99700
Draft payslips can now have their period date removed without causing an exception. This prevents interruptions for payroll users while editing payslips and adds test coverage to help keep the flow reliable.
Original PR description
When removing the date in a draft payslip an exception was raised. This was fixed and a test was added to check the flow. Related to odoo/odoo#231247 task-5159666 Forward-Port-Of: odoo/enterprise#99723 Forward-Port-Of: odoo/enterprise#97013
Fixed an issue that could prevent users from opening the payroll payrun view. This restores access to payrun information in the Payroll app after an underlying interface template changed.
Original PR description
Reproduce: 1. open payroll app 2. try to access the payrun view Issue: The `web.KanbanHeader` template is update and replace a `t-esc` with `t-out` when we have an xpath on the old value Solution: update the xpath expr Task: 5323275
Users with billing access can now revoke SEPA Direct Debit mandates even when those mandates have saved payment methods linked to customer portal payments. This prevents unnecessary access errors and lets finance teams manage mandate revocation without administrator intervention.
Original PR description
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** -…
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** - Enable SEPA Direct Debit payment provider in Test Mode - Create a mandate for a customer w/ valid IBAN - Create an invoice for that customer and post it - Action > Generate a Payment Link, open this in an incognito window - Pay using SEPA Direct Debit - Call `_set_done()` on the payment.transaction - Try to revoke the mandate as a non-admin with "Accounting / Billing" -> Access Error, can't modify payment.token **Cause:** - When SEPA Mandate is revoked, we check for all associated payment tokens (saved payment methods from SEPA Direct Debit payment provider) and deactivate them. - The check in code isn't called with sudo, so it uses the current user access rights, but only admins can modify the payment tokens in any way. **Solution:** - Write to the `linked_tokens` with sudo so we can archive the tokens regardless of user access opw-5136221 Forward-Port-Of: odoo/enterprise#99592 Forward-Port-Of: odoo/enterprise#99232
Fixes an issue where switching from one accounting report to a composite report could crash the interface when period comparison settings differed. Users can now change report variants more reliably without being interrupted by an error.
Original PR description
This fix a traceback: - Create a report "A" with Period Comparison set to True - Create a report "B" with Period Comparison set to False - Create a composite report with report "B" inside. - Use the…
This fix a traceback: - Create a report "A" with Period Comparison set to True - Create a report "B" with Period Comparison set to False - Create a composite report with report "B" inside. - Use the variant filter to switch from report "A" to the composite report This happens because of a UI refresh in `loadReportOptions` trigged by: - delete this.reportOptionsMap[cacheKey]; - delete this.loadingCallNumberByCacheKey[cacheKey]; When refreshing the UI, it will start with the cachedOption set to the value of the displayed report (report "A"), and is able to pass the condition inside `filters.xml`: `<t t-if="controller.filters.show_period_comparison">`. While this is happening, the loading of the new report "composite" reaches `this.cachedFilterOptions = options;`. However, the UI refresh is still ongoing, and when it reaches `<t t-if="controller.cachedFilterOptions.comparison.string">` in `filter_comparaison.xml`. If the new report doesn't have the comparaison filter enabled, cachedFilterOptions.comparison will be undefined triggering the traceback. This is fixed by marking the objects, that would trigger this useless refresh, as raw preventing them from triggering a refresh. This only happened on composite reports since the cacheKey used to load them is different from the one received by the call to get_options due to the sections. task-5085985 Forward-Port-Of: odoo/enterprise#99780
This update corrects how IoT websocket messages are sent so the message type is included as expected. It helps ensure websocket communication can be tested reliably and reduces the risk of issues in connected IoT workflows.
Original PR description
In order to allow testing the websocket protocol, we need to provide the message type to the `sendMessage` method. This was forgotten in odoo/enterprise#97525. Forward-Port-Of: odoo/enterprise#98568
The Belgian POS fiscal device integration now waits up to the documented limit and retries when the device returns an invalid or negative response. This reduces failed point-of-sale fiscal operations caused by temporary communication issues with the blackbox device.
Original PR description
Following documentation, max timeout should be 1.5s and we should retry 3 times on every bb NACK/invalid data. Forward-Port-Of: odoo/enterprise#99911 Forward-Port-Of: odoo/enterprise#99705
The Philippines .dat tax export now uses the same date period selected in the report, preventing files from showing a different period than the data they contain. Users also see a non-blocking warning when the chosen export frequency does not match the report period, helping reduce accidental filing errors while still allowing intentional exports.
Original PR description
Before this commit: - The `.dat` export adjusted its date based on the selected export type’s periodicity (quarterly or annually) using the report filter's date_to. - This caused mismatches where the…
Before this commit: - The `.dat` export adjusted its date based on the selected export type’s periodicity (quarterly or annually) using the report filter's date_to. - This caused mismatches where the `.dat` file showed a different period than the report data. - The adjustment only changed the date in header of `.dat` file but did not restrict data accordingly, leading to inconsistencies when exporting reports with different filter and periodicity types. - Example: If the report filter is set to 'October 2025' month and the export type's periodicity is 'Annual', the `.dat` file would show 12/31/2025 even though the data in `.dat` file only covers 'October 2025'. Similar mismatch occurs for 'month & quarter' and 'annual & quarter' combinations. After this commit: - The `.dat` export date now fully depends on the report’s date filter, keeping report data and export date consistent. - A non blocking warning is added in the `.dat` export wizard when the report period type is different from the export type's periodicity, helping users select the correct period type while still allowing export if intended. task-5172259 Forward-Port-Of: odoo/enterprise#99241
The due button on a contact now remains visible whenever that contact has at least one customer or vendor invoice, even if nothing is currently owed. This keeps quick access to financial details and customer statements available when teams need to review past activity.
Original PR description
The `Due Button` on `res.partner` is a convenient shortcut to access the partner’s current financial situation, especially the Customer Statement report. Even if the partner has no outstanding balance, the shortcut remains useful. So in this commit, we update the visibility logic of the `Due Button` so it appears as long as the partner has at least one `invoice (in/out)` linked to them. This means the button will remain visible even when the total `due amount is `zero`, ensuring the shortcut is always accessible. Task-5264512 Forward-Port-Of: odoo/enterprise#99514
The employee profile's Reviews button now correctly displays related contract review records after an offer is signed. This prevents users from seeing an empty list even when the button indicates records exist, improving confidence in employee contract workflows.
Original PR description
Issue:
When an offer is created and signed by the employee, the `Reviews` smart button appears on the employee profile. Although it indicates that there are records, clicking the button redirects to an empty list.
Reason:
After converting contracts to the versioning system, the action for the Reviews button does not properly display contract versions, regardless of whether they are active or inactive, as it did in the previous version.
Fix:
Added a context `{"active_test": False}` to show active or inactive records.
task-5155455
Forward-Port-Of: odoo/enterprise#96808The spreadsheet pivot side panel now respects debug mode when adding a column, so advanced users can search and see technical field names as expected. This restores the intended behavior for configuring pivot data in spreadsheets and reduces friction for support, implementation, and power users.
Original PR description
Steps to reproduce: - Activate debug mode - Insert a pivot in a spreadsheet - In the side panel, click on "Add column" => the component is not in debug mode, so the technical name cannot be searched and is not displayed Task: 5264589 Forward-Port-Of: odoo/enterprise#99484
This fix removes an overly strict rule that blocked users from choosing or copying certain tax groups when account types did not match expected categories. Businesses can again manage WinBooks tax group settings more flexibly without being prevented by a flawed validation.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Community PR:** https://github.com/odoo/odoo/pull/235548 opw-5231379 Forward-Port-Of: odoo/enterprise#99733 Forward-Port-Of: odoo/enterprise#99421
Payroll now respects the setting that disables change tracking when employees are edited through the salary configurator. This avoids unnecessary log entries and keeps employee records cleaner for HR teams.
Original PR description
We use a hack to force the tracking of some fields on the employee. It causes some problem when you work with the salary configurator as we don't want the changes logged in this case. The solution is to not track prepare the fields if there is a tracking disable in the context, like mail does. Forward-Port-Of: odoo/enterprise#99800
Sendcloud delivery methods now correctly recognize locker and combined locker/service point options as pickup locations. Customers using these services will be shown the location map so they can choose where their package should be dropped off.
Original PR description
Steps to reproduce ----- - Create a Sendcloud delivery method - Select a delivery service with "Locker or service point" as "Last mile" (eg "bpost @ bpack") > "Use Sendcloud locations" is set to…
Steps to reproduce ----- - Create a Sendcloud delivery method - Select a delivery service with "Locker or service point" as "Last mile" (eg "bpost @ bpack") > "Use Sendcloud locations" is set to false Cause ----- There is a problem with the values retrieved from the Sendcloud API call, more specifically the `available_functionalities` > `last_mile` value. The Sendcloud API (of both previous and current beta version) specifies the possible values to only be the following - `home_delivery` - `mailbox` - `pobox` - `service_point` - null https://api.sendcloud.dev/docs/sendcloud-public-api/shipping-options/operations/create-a-shipping-option https://api.sendcloud.dev/docs/sendcloud-public-api/branches/v2/shipping-products/operations/list-shipping-products However, it seems like they have added some new undocumented values `locker` and `locker_or_service_point`. To detect whether to use drop-off locations, we do https://github.com/odoo/enterprise/blob/5b64c63301bc814c7c9d99146af6a86d37563762/website_delivery_sendcloud/models/delivery_sendcloud.py#L51-L53 Where we compare the retrieved value with the string 'Service point' https://github.com/odoo/enterprise/blob/5b64c63301bc814c7c9d99146af6a86d37563762/website_delivery_sendcloud/models/delivery_sendcloud.py#L13 In our "Locker or service point" case, this does not work because the `in` operator makes a case sensitive comparison. Solution ----- Functionally, both lockers and service points work the same. The user should be prompted a map on which they choose where the delivery should be dropped off. So we can add `Locker` and `Locker or service point` as accepted values and enable the use of sendcloud locations for both. ----- Ticket: opw-5217796 Forward-Port-Of: odoo/enterprise#98875
The Uruguay electronic invoicing module now calculates currency rates consistently against the Uruguayan Peso, regardless of the company's base currency. This helps prevent incorrect exchange rates on electronic invoices for companies using non-UYU base currencies.
Original PR description
This PR fixes the currency rate calculation in the Uruguay EDI module to always compute the rate relative to UYU (Uruguayan Peso) regardless of the company's base currency. * Replaces the previous logic that calculated rates based on company currency with a direct UYU conversioni * Simplifies the rate calculation by removing the amount-based fallback logic * Ensures consistent UYU rate computation for all non-UYU currencies LATAM Task 1358 / Adhoc task 51716 Forward-Port-Of: odoo/enterprise#99587 Forward-Port-Of: odoo/enterprise#93144
This update improves the appointment booking experience by placing the guest option after all registration questions, so customer forms appear in a more logical order. It also corrects when the “Add Closing Day(s)” button appears, ensuring it is available for resource bookings and hidden for staff bookings as intended.
Original PR description
Purpose ======= Fix various interface issues related to the appointment app following the Testing Days for v19. Specification =========== - Placing add guests button after registration questions on…
Purpose ======= Fix various interface issues related to the appointment app following the Testing Days for v19. Specification =========== - Placing add guests button after registration questions on front-end. Following the addition of a phone question type (odoo/enterprise#82973), the user phone input at registration is in the list of questions and not at the top of the form in the base user information section anymore. The Add Guests feature can thus be displayed before the phone number which seems a bit odd. Fixing the issue by moving the Add Guests feature at the end of the form, after the list of questions. - Fix the "Add Closing Day(s)" button visibility. The button should be visible on every resource views (gantt, calendar, list), and should be invisible on every staff booking views (gantt, calendar, list). Currently, the button is visible on the list view for staff bookings, it should not. The button is also not present on the calendar view for resource bookings, it should be. Task-5079021 Forward-Port-Of: odoo/enterprise#96027
Salary offers created from the Offers list now receive a valid access link, matching the behavior of offers generated from an applicant record. This prevents broken offer links and adds safeguards so public visitors cannot open offers tied to employees who should sign in.
Original PR description
#### Steps to Reproduce - Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list…
#### Steps to Reproduce - Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list view, click "New" to create an offer. - Compare both flows: * With "Generate Offer" button: the generated offer link has a valid token and works even in an incognito window. * With "New" button: the generated offer link has `token=False`, which leads to an invalid link. #### Issue In the first scenario, `action_generate_offer()` generates an `access_token` for the offer's link in `hr.applicant`. In the second scenario, no token was generated in `hr.contract.salary.offer`, so offers created via the "New" button end up with `access_token=False` in their links. #### Fix - Add a compute to `access_token` in `hr.contract.salary.offer` to generate a token if there is no employee or if the employee on the offer has no linked user. - Update controller logic to prevent public users from accessing an offer link if the offer's employee has a linked user. task-5051394 Forward-Port-Of: odoo/enterprise#98856
Employees and contract templates no longer require a Pay Category, so freelancers or people without an occupation can be managed without unnecessary setup. Payroll runs will automatically skip employees without a Pay Category, and form guidance now explains this behavior.
Original PR description
The field is always required in the employee and contract template form views, but a Freelancer, or people without occupation should not bother with it. There was a check on the pay category during the payslip creation which is now removed since the payslip is computed based on the pay structure on the payslip form not the one on the employee profile. Employees without a pay category will be excluded from pay runs, therefore the "Pay Category" placeholder in form views has been updated to indicate so. Task-5237800 Forward-Port-Of: odoo/enterprise#98921
The Philippines Summary Lists of Sales and Purchases report now correctly shows the Registered Name for company contacts. This prevents blank company names in the report and keeps exported files accurate for both companies and individuals.
Original PR description
**Steps to reproduce:** 1. Install the `Accounting` and `l10n_ph_reports` modules. 2. Create a contact with the company flag enabled. 3. Create an invoice using that contact. 4. Go to `Reporting →…
**Steps to reproduce:**
1. Install the `Accounting` and `l10n_ph_reports` modules.
2. Create a contact with the company flag enabled.
3. Create an invoice using that contact.
4. Go to `Reporting → Summary Lists of Sales and Purchases → Sales`.
**Observed behavior:**
* The `Registered Name` column in the report is blank for companies.
**Cause:**
* The query logic was incorrectly showing the registered name only when a last name was present. This issue arose due to the change in how company/individual differentiation is handled.
**Fix:**
* Update the query logic for the Odoo report:
- **Always display the registered name in the Odoo report**:
- If individual: show `First Name`, `Middle Name`, `Last Name`.
- If company: show `commercial_partner_id.name`.
- **For the export file**:
- If company: only show the registered name.
- If individual: show `First Name`, `Middle Name`, `Last Name`.
The fix ensures that **Registered Name** is always displayed in the report, and the export behaves as expected for both individuals and companies.
Note: spec provided by po ->
<img width="1662" height="431" alt="image" src="https://github.com/user-attachments/assets/a7a58a9e-b769-4815-ad0a-cef9c8e2eff7" />
opw-5143677
Forward-Port-Of: odoo/enterprise#99075Check messages in the EU OSS reports now display in a cleaner, more consistent format. This improves readability for users reviewing report checks and removes an awkward multi-line presentation issue.
Original PR description
Multi-line messages for checks are displayed on multiples lines starting in 19.0. This is ugly and we fix this so every checks have a similar look. Before: <img width="368" height="103" alt="image" src="https://github.com/user-attachments/assets/67bb84f9-ac61-4c0d-84ba-b8a886763546" /> After: <img width="337" height="74" alt="image" src="https://github.com/user-attachments/assets/4f45b368-cf60-4b46-b10a-dd1b75ceb9f9" /> Forward-Port-Of: odoo/enterprise#99772
This update ensures bills include the required bill date in accounting and localization workflows. It helps prevent validation errors and keeps Colombian DIAN, Spanish reports, prediction, and Intrastat purchase processes consistent.
Original PR description
task-5214234 Forward-Port-Of: odoo/enterprise#99650
26 changes
Resolved issues and error corrections
The message action menu now reliably shows “Copy to Clipboard” for regular conversations, even when the AI module is installed. This fixes a missing option that could prevent users from copying message text in chat and discuss views.
Original PR description
Before this commit, "Copy to Clipboard" was sometimes not visible in the message action list when message had some text content. This happens because message actions can condition overridden by some…
Before this commit, "Copy to Clipboard" was sometimes not visible in the message action list when message had some text content. This happens because message actions can condition overridden by some other modules, and the way overrides of action condition work is to have boolean value taking precedence over the local condition of action. This architecture is meant to provide exhaustive list of actions to allow, which is quite useful to control what livechat visitors can have. However this architecture requires overrides to properly return `undefined` when the local condition should apply, which was not the case for an override by `ai` module. So when `ai` module is installed, the "copy to clipboard" feature as not available. This commit fixes the issue by adapting the condition in `ai` module to return `undefined` on non-AI conversations, and add test coverage for both `@mail` discuss suite and all overrides of discuss in `@test_discuss_full_enterprise`. opw-5240768 https://github.com/odoo/enterprise/pull/99794
This update changes how Odoo finds Peppol service providers so it stays compatible with upcoming DNS changes. It helps avoid failed lookups and keeps electronic document exchange working reliably as the old method is phased out.
Original PR description
From November 1st, CNAME DNS will be deprecated for Peppol lookups. From February 1st CNAME lookups will no longer be supported. The replacement are NAPTR DNS records. Multiple solutions were available, such as using DoH (e.g. with cloudflare DNS), but we ended up choosing to proxy DNS requests through IAP to centralize the lookups and make such specs upgrades easier to handle in the future. IAP is now responsible of doing the DNS lookup and fetching the service groups of the found SMP. IAP-side: https://github.com/odoo/iap-apps/pull/1227 task-5179969 Forward-Port-Of: odoo/odoo#233766 Forward-Port-Of: odoo/odoo#232483
The Job Page button on job listings now appears only when Online Posting is enabled, and stays hidden when it is disabled. This avoids confusion and makes the button match the job’s publishing status, while still linking directly to the job page when available.
Original PR description
This commit fixes the visibility of the "Job Page" button on the job kanban view. The job page button is now invisible when the `Online Posting` setting is disabled and visible when it is enabled, and directs to the job link. task-5153230 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233421
The Copy to Clipboard action now appears correctly again for regular conversations, even when the AI module is installed. This fixes a missing option in the message menu and improves consistency for users and support teams.
Original PR description
Before this commit, "Copy to Clipboard" was sometimes not visible in the message action list when message had some text content. This happens because message actions can condition overridden by some…
Before this commit, "Copy to Clipboard" was sometimes not visible in the message action list when message had some text content. This happens because message actions can condition overridden by some other modules, and the way overrides of action condition work is to have boolean value taking precedence over the local condition of action. This architecture is meant to provide exhaustive list of actions to allow, which is quite useful to control what livechat visitors can have. However this architecture requires overrides to properly return `undefined` when the local condition should apply, which was not the case for an override by `ai` module. So when `ai` module is installed, the "copy to clipboard" feature as not available. This commit fixes the issue by adapting the condition in `ai` module to return `undefined` on non-AI conversations, and add test coverage for both `@mail` discuss suite and all overrides of discuss in `@test_discuss_full_enterprise`. opw-5240768 https://github.com/odoo/odoo/pull/236295
Odoo now adds a timestamp suffix to Flutterwave payment references so each transaction sent to the provider stays unique. This prevents duplicate reference issues when databases are reset during testing or in similar edge cases, improving payment reliability.
Original PR description
The `/payments` endpoint of the Flutterwave v3.0.0 API expects unique `tx_ref` parameters (matching Odoo's payment transaction `reference` field) to be passed. This is guaranteed by a UNIQUE() SQL constraint in Odoo, but testing sometimes involves dropping the database, leading to transaction references being repeated at the provider level for a given merchant account. This commit singularizes all transaction references by suffixing them with the current timestamp, ensuring that the `tx_ref` API parameter remains unique across transaction reference sequences. Forward-Port-Of: odoo/odoo#235799
Users can now export records even when the list is grouped by a property field. This fixes a crash that happened during export, improving reliability for grouped views and avoiding interruption of normal work.
Original PR description
Step to reproduce
- open a task
- add a property field , say test
- add values for this field in few records
- go to list view and group by test
- select a record from result and export it (from Action btn)
Observation:
- traceback
```
File "/home/odoo/17.0/addons/web/controllers/export.py", line 486, in base
groupby_type = [Model._fields[x.split(':')[0]].type for x in groupby]
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: 'task_properties.b60ee9baefee14a8'
```
Cause:
- The issue is caused by splitting, which didn't considered property field
- it tried to look for `task_properties.b60ee9baefee14a8` in _fields which causes KeyError
FIx:
- split the field name properly to bring out actual field name while considering granularity as well as the property fields
opw-5159155
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235979
Forward-Port-Of: odoo/odoo#235209Vendor batch payments now use the correct numbering sequence when they are created and validated. This prevents vendor batches from being labeled with the wrong type of sequence, which could cause confusion in accounting records.
Original PR description
Currently when creating a vendor batch payment, the system may incorrectly use the inbound batch payment sequence to generate the batch name Steps to reproduce: - Create a Vendor payment. - Create a Vendor batch payment, add the payment, validate it. Issue: Name has been set using the incoming batch payment sequence This occurs because `batch_type` is set to readonly when a payment is added to the list. As result, the current batch type is never sent to the backend that will use the default 'inbound'. opw-5128426 Forward-Port-Of: odoo/enterprise#99570
This update corrects how returned subcontracted products are routed so they go back to the appropriate location instead of all being sent to the subcontracting area. It prevents the system from accidentally changing delivery locations during the return process, which helps avoid stock errors and makes returns more reliable.
Original PR description
Steps to reproduce the bug: - Create a storable product "P1" and "P2" with vendor "azure interior" - for P2 subcontracting BoM referencing "azure interior" as subcontractor and component "C1" -…
Steps to reproduce the bug: - Create a storable product "P1" and "P2" with vendor "azure interior" - for P2 subcontracting BoM referencing "azure interior" as subcontractor and component "C1" - Create a receipt for partner "azure interior" including 1 unit of P1 and 1 unit of P2 - Validate the receipt - Create a return for both P1 and P2 Problem: A picking is created with destination location set to the subcontracting location for both products, instead of setting the partner location only for subcontracted products. Solution: Ensure only the move line for subcontracted products uses the subcontracting destination location, while other returned products go back to the supplier location. When the `picking_id.partner_id`` is changed, it triggers a write on the picking, which in turn triggers a write on its moves, but only on the ones that are not scrapped. However, since the `scrapped`` field is a stored computed field, and as it hasn't been accessed before, it needs to be computed. And because its computation depends on `location_dest_id`, that field also needs to be recomputed. as a result, the `location_dest_id`` of the moves that we manually set may be changed unexpectedly. Therefore, in the `_create_return`` function, we check that the picking’s `partner_id` is different from the moves’ partner_id before updating it, to avoid unnecessary writes and the chain of recomputations that could alter our values. Resetting the picking’s partner_id based on the move’s partner_id could actually be removed in master, as it serves no real purpose, the move.partner_id itself is already derived from the picking’s partner_id. We just keep it in stable versions to avoid any unexpected behavior changes. opw-5208289 Forward-Port-Of: odoo/odoo#234850 Forward-Port-Of: odoo/odoo#234521
Fixed an issue where the “Update extra prices” action could disappear too early after a form save, even when not all variant prices had been synchronized. This helps ensure all affected product variants can be updated consistently before being used in sales orders.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update…
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update extra prices"; 5. add the updated variants to a sale order. Issue ----- Only the line on which "Update extra prices" was clicked has been updated, even though the button disappeared on all lines after clicking it. Cause ----- The `_compute_default_extra_price_changed` method only compares the `default_extra_price` of the current record to its `_origin` value. Consequently, after saving the form, it will return `False`, even though only one attribute has been updated. Solution -------- Aside from checking whether the value changed on the form, also check whether any product template attribute value has a `price_extra` that's different from the product attribute value's `default_extra_price`. This way, clicking on "Update extra prices" once won't make the other update buttons disappear. opw-5240236 Forward-Port-Of: odoo/odoo#235088
This update ensures payment references keep the intended prefix when generating a unique reference. It helps avoid confusion and reduces the risk of duplicate-looking transaction names for payments processed through Paymob.
Original PR description
Forward-Port-Of: odoo/odoo#236015
The Activities menu now keeps pagination working even when some activities are filtered out by access rules. This prevents users from getting stuck on the first page and makes it possible to browse all activities they are allowed to see.
Original PR description
**Steps to reproduce:** - Create some activities which should not be accessible to a specific user (according to the `_search` filtering of `mail.activity`) - Go to Activity Menu > View all…
**Steps to reproduce:** - Create some activities which should not be accessible to a specific user (according to the `_search` filtering of `mail.activity`) - Go to Activity Menu > View all activities as the given user - Ensure that the limit (default: 80) is lower than the total number of activities which should be returned and that the new activities are in the returned elements - On `web_search_read` some records are removed by the `_search` override - The pagination navigation buttons are disabled as the returned number of records is lower than the limit - This means that some activities are not accessible to the user (everything above the given limit) **Issue:** The issue comes from the `_search` override which checks the records available to the user. As it's done after fetching with the limit, the resulting number of records can be lower than expected and this breaks the `_format_web_search_read_results` which considers that we have all the possible records and doesn't try to fetch the total count of records. **Fix:** The main issue can't be directly fixed without modifying the way the access are checked in the `_search` override. This could be mitigated by changing the search limit, making the search as superuser, or adding specific filtering but each has its own limitations. Adding `force_search_count` should allow the user to navigate between pages anyway and see all the available activities. But the number displayed in the pagination will often be incorrect for the current and total count. (e.g. we can have 75 records but 1-80/150 is displayed out of 140 actually readable records) opw-5046389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233585
This update adds a database index to a field used to link invoice symbols with invoice templates in the Vietnam e-invoicing module. It helps the system retrieve related records more efficiently and keeps the module aligned with Odoo’s performance rules.
Original PR description
TestIndex.test_enforce_index_on_one2many_inverse Traceback (most recent call last): AssertionError: The following fields should be indexed with a btree index, as they are inverse of an One2many field: - if the field is sparse -> 'btree_not_null' - if the field is Required or low fraction of False/NULL values -> True or 'btree' - if not sure -> 'btree_not_null': l10n_vn_edi_viettel.sinvoice.symbol.invoice_template_id (inverse of l10n_vn_edi_viettel.sinvoice.template.invoice_symbols_ids) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prevents an error that could happen when a user adds a product from the sales catalog and immediately removes it. Instead of failing, the system now correctly uses the product’s sale price, so the sales order remains usable and the user can continue working smoothly.
Original PR description
Currently, an error occurs when the user immediately removes a catalog product after adding it. Steps to Reproduce ([Video](https://drive.google.com/file/d/12hOavt1zCa6hbG0EWHsIDGxfgVkxJmLW/view)): -…
Currently, an error occurs when the user immediately removes a catalog product after adding it. Steps to Reproduce ([Video](https://drive.google.com/file/d/12hOavt1zCa6hbG0EWHsIDGxfgVkxJmLW/view)): - Install the `sale_management` module. - Go to `Sales Orders` and create a new `sale order`. - In the order line, click on the `Catalog` button. - `Add` a product and then immediately `remove` it. `ValueError: Expected singleton: sale.order.line()` After [this commit], when the user clicks the Remove button immediately after clicking the Add button (within 500 ms). In this case, the system proceeds with the last request due to the useDebounced delay [1], which removes the product. However, since there is no order line yet for that product [2] and the quantity is 0, the order line [3] is not created. When it attempts to retrieve the discounted price, it raises the error [4]. This commit ensures that if no order line exists, the product's price is returned according to the sale order's pricelist. [this commit]: https://github.com/odoo/odoo/pull/233098/commits/697c559791fdf00b5602b9459bbdf21f392757d8 [1]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/product/static/src/product_catalog/kanban_record.js#L17-L19 [2]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order.py#L2202 [3]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order.py#L2218-L2219 [4]- https://github.com/odoo/odoo/blob/ec212f38e50520edf612522717952855c8c09a80/addons/sale/models/sale_order_line.py#L1602-L1603 sentry-7019831319 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235470
We fixed an issue that could cause the QAP & SAWT report to crash when users switched to it from another report. The report now waits for its related filter information to be ready before showing the page, so it opens reliably and smoothly.
Original PR description
Before: - When switching from another report to the SAWT & QAP report, it gave traceback. - The traceback happened because the system tried to read missing data in the comparison filter. After: - Added a proper check so the report only loads the comparison filter when it exists. - Switching between reports now works smoothly without errors. Impact: - QAP & SAWT report opens reliably without unexpected crashes. Task: 5085985
The appointment page in the website editor could crash when users clicked Edit, preventing them from making changes. The template was adjusted so the page keeps the same look while avoiding a layout structure that confused the editor, restoring normal editing.
Original PR description
#### Steps to Reproduce 1- Create a fresh database on Odoo 19.0. 2 - Install both the Appointments and Website modules. 3 - Go to the website appointment page generated by the module. 4 - Click Edit…
#### Steps to Reproduce
1- Create a fresh database on Odoo 19.0.
2 - Install both the Appointments and Website modules.
3 - Go to the website appointment page generated by the module.
4 - Click Edit in the website builder.
5 - The website editor crashes with the SelectionPlaceholderPlugin error.
#### Issue
After Odoo 19 introduced the new [SelectionPlaceholderPlugin](https://github.com/odoo/odoo/blob/19.0/addons/html_editor/static/src/main/selection_placeholder_plugin.js) in the HTML editor, the appointment progress bar view began to crash, specifically when clicking the “Edit” button of the website editor on the appointment page.
This issue did not occur in earlier versions because the plugin did not exist. And the old editor never scanned or validated raw text nodes.
The appointment progress bar template contained a `li` node using d-flex directly on the `li` element.
In Odoo 19, the HTML Editor’s selectionPlaceholder plugin inspects the DOM after every render to determine where the selection placeholder blocks must be inserted.
Because d-flex changes the internal layout of the `li`, Owl and the HTML editor produces intermediate text nodes / inline nodes inside the flex container. During placeholder evaluation, the editor scans siblings before/after each block using:
```python
selection_blocker_predicates(blocker)
```
This logic expects HTML elements, as it calls:
```python
blocker.hasAttribute(...)
```
However, the flex layout caused the plugin to receive a non-element node (e.g. a TextNode) as blocker.
Since TextNodes do not implement .hasAttribute(), the editor raised:
```python
TypeError: blocker.hasAttribute is not a function
```
This error propagated into:
```python
OwlError: An error occurred in the Owl lifecycle
```
which broke the entire website editor.
#### Traceback
```python
UncaughtPromiseError > OwlError
Uncaught Promise > An error occurred in the Owl lifecycle (see this Error's "cause" property)
Occurred on localhost:8069 on 2025-11-11 13:57:55 GMT
OwlError: An error occurred in the Owl lifecycle (see this Error's "cause" property)
Error: An error occurred in the Owl lifecycle (see this Error's "cause" property)
at handleError (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:762:101)
at App.handleError (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:1420:29)
at ComponentNode.initiateRender (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:854:19)
Caused by: TypeError: blocker.hasAttribute is not a function
at selection_blocker_predicates (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:14305:1708)
at http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:14306:115
at Array.map (<anonymous>)
at checkPredicate (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:14306:106)
at isSelectionBlocker (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:14306:243)
at SelectionPlaceholderPlugin.updatePlaceholders (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:14307:272)
at http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:12434:52
at Array.forEach (<anonymous>)
at Editor.startPlugins (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:12434:38)
at Editor.attachTo (http://localhost:8069/web/assets/1/d4f733d/web.assets_web.min.js:12425:6)
```
#### Fix
To avoid creating confusing DOM structures for the editor, the template was updated to:
- Wrap the inner content to keep the same UI layout without affecting the parent `li` block semantics.
##### This insure
- The items stay a clean block-level element.
- The HTML editor correctly identifies block boundaries.
- The selection placeholder plugin no longer receives invalid nodes.
OPW - [5226904](https://www.odoo.com/odoo/project/70/tasks/5226904)This fix prevents an error that could occur when a purchased product receipt is edited and its quantity is changed to zero. Instead of crashing, the product’s value remains unchanged, allowing the user to save the receipt normally.
Original PR description
Currently an error occurs when user change the move line quantity. Steps to Reproduce [video](https://drive.google.com/file/d/12r0DxsKZkvuVjoCsRgXlHJ23NpaqciV7/view?usp=drive_link): - Install the…
Currently an error occurs when user change the move line quantity. Steps to Reproduce [video](https://drive.google.com/file/d/12r0DxsKZkvuVjoCsRgXlHJ23NpaqciV7/view?usp=drive_link): - Install the `purchase_stock` module. - Create a `product` with category: `Costing Method: FIFO`. - Create a `purchase order` and add the newly created product to it. - Click `Confirm Order`, then click on `Receipt` and `validate` it. - Click on `Moves`, open the record, set the `Quantity to zero`, and `save`. `ZeroDivisionError: float division by zero` This error occurs when a user confirms a purchase order, validates its picking, and changes the move line quantity to zero. It then tries to update the move line value and the product's standard price due to the FIFO costing method, but the valued quantity becomes zero from [1], which raises an error at [2]. This commit ensures that if the move line has a zero quantity, the product's standard price remains unchanged. [1]- https://github.com/odoo/odoo/blob/f8f72b15598576f5870e49879e96fc5c127a6100/addons/stock_account/models/stock_move.py#L333-L343 [2]- https://github.com/odoo/odoo/blob/f8f72b15598576f5870e49879e96fc5c127a6100/addons/stock_account/models/product.py#L218 sentry-6993648057 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents a server error when using the “eCommerce Categories” option in the website mega menu. The menu now correctly detects the relevant mega menu element even when the first item inside it is not the expected one, making the website editor more reliable.
Original PR description
A server traceback would occur when clicking the "eCommerce Categories" toggle in the mega menu's style options. Steps to reproduce: 1. Go to the Website editor. 2. Add a mega menu to the page header. 3. Edit and Click on the mega menu's 4. In the sidebar, click the "eCommerce Categories" toggle. -> Traceback. Cause: When loading it was trying to find a specific class name (starting with `s_mega_menu_`) to identify the snippet. It was hardcoded to only look at the `firstElementChild` of the snippet's container. This assumption was too rigid. If the first element was a `<p>` tag or another element without the required class, the code would fail to find it. This resulted in an `undefined` value being sent to the server, causing the traceback. Solution: Use `querySelector` to search for any element with a class name containing `s_mega_menu_`. opw-5245777 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
We fixed an issue where offers created from the offer list could generate an invalid link. Now every offer gets a proper access token, so the link works reliably, including when opened outside the logged-in session. This prevents broken offer pages for candidates and employees.
Original PR description
- Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list…
- Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list view, click "New" to create an offer. - Compare both flows: * With "Generate Offer" button: the generated offer link has a valid token and works even in an incognito window. * With "New" button: the generated offer link has `token=False`, which leads to an invalid link. #### Issue In the first scenario, `action_generate_offer()` generates an `access_token` for the offer's link in `hr.applicant`. In the second scenario, no token was generated in `hr.contract.salary.offer`, so offers created via the "New" button end up with `access_token=False` in their links. #### Fix Add a compute to `access_token` in `hr.contract.salary.offer` to generate a token if there is no employee or if the employee on the offer has no linked user. #### Additional - Mark the field `access_token` as readonly. task-5051394 Forward-Port-Of: odoo/enterprise#93561
This fix improves the message shown when an accounting entry is not balanced. If several entries are affected, users will now see the full list instead of only the first one, making it easier to identify and resolve the issue.
Original PR description
The commit 3467b5971423f70581c6be2caf7f8a8d86ee70f1 intended to improve the error message in `_check_balanced()` by tailoring it based on the number of affected entries. However, in the case of multiple affected entries, the error was raised after the first iteration, preventing the full list of unbalanced entries from being collected and displayed to the user. no-task --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236212
This fix ensures landed costs are only applied to the quantity that is still in stock, instead of increasing the value of goods that have already been delivered. It keeps inventory valuation accurate and prevents reports from showing inflated values for products no longer on hand.
Original PR description
## Issue: When adding landed costs to stock moves, the resulting move value was increased regardless of the quantity remaining in stock As a result, moves with no remaining quantity could still…
## Issue: When adding landed costs to stock moves, the resulting move value was increased regardless of the quantity remaining in stock As a result, moves with no remaining quantity could still receive additional value, incorrectly affecting products that are no longer in stock ## Cause: The valuation is determine using the `move._get_value()` function, which uses the standard price when there is no linked PO, Bill, or Credit Note However, it distributed the landed cost share based on the move itself, without considering whether the move’s quantity was still available in stock ## Steps to reproduce: - Create a product (Tracking: Quantity, category: AVCO) - Receive 2 units of the product. - Deliver 1 unit - Create a Landed Cost for the receipt with an additional cost of 100 $ - Open Inventory > Reporting > Move Analysis - Add Value in Measures - Look for the current month (add a product filter if needed) - You should have Quantity: 2 and Value: 50$ after the fix opw-5128570 Forward-Port-Of: odoo/odoo#232857 Forward-Port-Of: odoo/odoo#231936
This update stops the system from recording unnecessary field changes when using the salary configurator. It helps keep employee change history accurate and avoids confusing log entries during payroll setup.
Original PR description
We use a hack to force the tracking of some fields on the employee. It causes some problem when you work with the salary configurator as we don't want the changes logged in this case. The solution is to not track prepare the fields if there is a tracking disable in the context, like mail does.
This fix lets managers refuse a validated time-off allocation even if leave records already exist in that period. Previously, the system could wrongly block the refusal by linking those existing leaves to the newer allocation, making it harder to correct the record.
Original PR description
## Issue: When you have an allocation and set a leave for that period, if you add a new allocation for that period and you validate it, it will be impossible to Refuse this allocation later A…
## Issue: When you have an allocation and set a leave for that period, if you add a new allocation for that period and you validate it, it will be impossible to Refuse this allocation later A UserError was raised asking to remove the leave even if it should be linked to the first allocation created ## Cause: The `action_refuse()` method for `hr.leave.allocation` uses the `virtual_leaves_taken` value inside the `_get_consumed_leaves()` function's result That parameter is calculated for the allocation as far as it state is `validate`, for all the leaves in that time interval, including previously created leaves The leaves will be allocated to the last allocation created, so the last one can't be removed later As a result, the allocation is considered as already used by these pre-existing leaves, even if the leave can still be modified to return to the state prior to the allocation's validation ## Steps to reproduce: - Create an initial Allocation (that should end after the next created Allocation) - Create a Leave from 22/12/2025 to 31/12/2025 - Create an Allocation including the leave period (01/12/2025 to 31/12/2025) - Validate, then Refuse opw-4900686 Forward-Port-Of: odoo/odoo#235711 Forward-Port-Of: odoo/odoo#222171
This update fixes the Philippine Summary Lists of Sales and Purchases report so company customers now appear with their registered name again. It also ensures exported files show the correct name format for both companies and individuals, improving report accuracy and compliance.
Original PR description
**Steps to reproduce:** 1. Install the `Accounting` and `l10n_ph_reports` modules. 2. Create a contact with the company flag enabled. 3. Create an invoice using that contact. 4. Go to `Reporting →…
**Steps to reproduce:**
1. Install the `Accounting` and `l10n_ph_reports` modules.
2. Create a contact with the company flag enabled.
3. Create an invoice using that contact.
4. Go to `Reporting → Summary Lists of Sales and Purchases → Sales`.
**Observed behavior:**
* The `Registered Name` column in the report is blank for companies.
**Cause:**
* The query logic was incorrectly showing the registered name only when a last name was present. This issue arose due to the change in how company/individual differentiation is handled.
**Fix:**
* Update the query logic for the Odoo report:
- **Always display the registered name in the Odoo report**:
- If individual: show `First Name`, `Middle Name`, `Last Name`.
- If company: show `commercial_partner_id.name`.
- **For the export file**:
- If company: only show the registered name.
- If individual: show `First Name`, `Middle Name`, `Last Name`.
The fix ensures that **Registered Name** is always displayed in the report, and the export behaves as expected for both individuals and companies.
Note: spec provided by po ->
<img width="1662" height="431" alt="image" src="https://github.com/user-attachments/assets/a7a58a9e-b769-4815-ad0a-cef9c8e2eff7" />
opw-5143677This update fixes an issue where some Sendcloud delivery services could not show drop-off point selection during checkout. Customers can now choose a locker or service point on the map when the delivery method supports it, improving the delivery experience and preventing missing options at checkout.
Original PR description
Steps to reproduce ----- - Create a Sendcloud delivery method - Select a delivery service with "Locker or service point" as "Last mile" (eg "bpost @ bpack") > "Use Sendcloud locations" is set to…
Steps to reproduce ----- - Create a Sendcloud delivery method - Select a delivery service with "Locker or service point" as "Last mile" (eg "bpost @ bpack") > "Use Sendcloud locations" is set to false Cause ----- There is a problem with the values retrieved from the Sendcloud API call, more specifically the `available_functionalities` > `last_mile` value. The Sendcloud API (of both previous and current beta version) specifies the possible values to only be the following - `home_delivery` - `mailbox` - `pobox` - `service_point` - null https://api.sendcloud.dev/docs/sendcloud-public-api/shipping-options/operations/create-a-shipping-option https://api.sendcloud.dev/docs/sendcloud-public-api/branches/v2/shipping-products/operations/list-shipping-products However, it seems like they have added some new undocumented values `locker` and `locker_or_service_point`. To detect whether to use drop-off locations, we do https://github.com/odoo/enterprise/blob/5b64c63301bc814c7c9d99146af6a86d37563762/website_delivery_sendcloud/models/delivery_sendcloud.py#L51-L53 Where we compare the retrieved value with the string 'Service point' https://github.com/odoo/enterprise/blob/5b64c63301bc814c7c9d99146af6a86d37563762/website_delivery_sendcloud/models/delivery_sendcloud.py#L13 In our "Locker or service point" case, this does not work because the `in` operator makes a case sensitive comparison. Solution ----- Functionally, both lockers and service points work the same. The user should be prompted a map on which they choose where the delivery should be dropped off. So we can add `Locker` and `Locker or service point` as accepted values and enable the use of sendcloud locations for both. ----- Ticket: opw-5217796 Forward-Port-Of: odoo/enterprise#98875
This update corrects a missing reference in the Point of Sale cash move popup so new orders include the right configuration information. It helps avoid receipt printing problems when handling cash moves.
Original PR description
Before this commit, the cash move popup created an order that missing the config_id field, leading to potential issues in receipt printing. opw-5251257 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236203
This change fixes WebSocket timeout handling so stalled connections are detected and closed correctly. It improves reliability by making sure the system does not leave connections hanging when the other side stops responding.
Original PR description
This PR fixes several issues with WebSocket timeouts: - Waiting for more than one response was not handled properly, resulting in missed timeouts. - The closing handshake did not strictly follow the RFC when initiated on the server side (it closed without waiting for the other peer). - Close timeouts were not enforced (the connection was not terminated when the other peer did not respond to the close frame). Forward-Port-Of: odoo/odoo#236016 Forward-Port-Of: odoo/odoo#234881
16 changes
Resolved issues and error corrections
When opening Shop Floor from a Manufacturing Order, the system now shows the work center that belongs to that order instead of reusing the last one the user viewed. This prevents users from landing on the wrong screen and makes it easier to see the relevant order context immediately.
Original PR description
Opening shop floor from MO smartbutton activates the WC "Overview". Subsequent opening of shopfloor app will also land on WC "Overview". Also removes an 'undefined' part of local storage key. BEFORE:…
Opening shop floor from MO smartbutton activates the WC "Overview". Subsequent opening of shopfloor app will also land on WC "Overview". Also removes an 'undefined' part of local storage key. BEFORE: Due to an oversight during this fix odoo/enterprise#93553, opening shop floor from MO smartbutton selects the WC from local storage (ie last clicked by user), with a filter for the current MO. (ie. when clicking Shopfloor smartbutton on an MO we can land on the wrong WC) NOW: Opening shop floor from MO smartbutton selects the WC "All MO" with a filter for the current MO. If we close shopfloor and come back to the shop floor app we land back on the "All MO" WC, which is the intended behaviour. Note: I did not rewrite tests I did here: https://github.com/odoo/enterprise/pull/93553/files#diff-2aa7dbd54334d280c72d91b7d472077aaae9af017408f1b0d71150bb16a022f4 as the setup is quite different in 18.0 (no access to the required stepUtils and the tour flow is quite different) task#4629641
This fix prevents customers from seeing technical error pages when an unusual rental setup creates an order without valid rental dates. Instead of crashing during checkout, the website now handles the situation gracefully so the customer experience is not interrupted by a traceback.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have `website_event_sale` but not `stock` installed; 2. create an event with a ticket; 3. make the ticket's product rentable; 4. change ticket's product type to Goods; 5. publish the event to website; 6. register for the event via website; 7. go to payment. Issue ----- AttributeError: 'bool' object has no attribute 'tzinfo' Cause ----- Having odd configurations like rentable tickets creates rental orders without rental dates, leading to unhandled errors. Solution -------- While rentable event tickets doesn't make enough sense to make it work, we can still improve the error handling to prevent showing tracebacks to the client. opw-5207045 Forward-Port-Of: odoo/enterprise#99000
This update fixes an issue where the chosen warehouse could be replaced by a different one when enabling inter-company purchase order settings. It helps companies with multiple warehouses keep the correct warehouse selection, avoiding unintended changes in their setup.
Original PR description
Issue: -------- While having multiple companies, multiple warehouses and when different warehouses are set for different companies other than the first one(id=1) under Inter-Company Transactions "Use…
Issue: -------- While having multiple companies, multiple warehouses and when different warehouses are set for different companies other than the first one(id=1) under Inter-Company Transactions "Use Warehouse". Now, when we check the 'Generate Purchase Orders' then the 'Use Warehouse' value which was set before is getting overridden to the first Warehouse which has minimal 'id'. Cause: ------ [Here](https://github.com/odoo/enterprise/commit/6324a6bab04fa0f3aa6d87deabc44c7c2eafc295#diff-51563a07f4b65f4ffe54bfb161ac1e9e58ff0f0bcf2522c9f6aa3746b60a68adR28-R38) Since, whenever there's a change within any of those check-boxes the compute will be triggered and the values will get modified. During this trigger the value set in the 'Use Warehouse' is getting overridden to the warehouse with minimal 'id'(For ex: id-1). Solution: ----------- To fix this, we'll just check if there's no value set before. If yes, then we'll set the first warehouse which has minimal 'id'. Otherwise, set the one which is selected. Steps to reproduce: ------------------------- 1. Create a fresh db with multiple warehouses and 'sale_purchase_stock_inter_company_rules' module installed. 2. Go to General Settings> Inter-Company Transactions and check/select 'Generate Sale Orders' and set a different warehouse and save. 3. Now check/select the 'Generate Purchase Orders' and save. 4. Look at the Use Warehouse value in the Settings. It will be the first one with minimal 'id'. Ref PRs: 1. https://github.com/odoo/enterprise/pull/55350
This change prevents the system from applying the same customer payment twice when a subscription includes products billed at different times. When a subscription is confirmed and paid through the portal, all items are now included in the first invoice so later recurring invoices are handled correctly.
Original PR description
Version: - 18.0 Steps to reproduce: 1. create a subscription with a mixed invoice_policy (order + delivered) 2. pay through the portal 3. on the next_invoice_date of the subscription: - set…
Version: - 18.0 Steps to reproduce: 1. create a subscription with a mixed invoice_policy (order + delivered) 2. pay through the portal 3. on the next_invoice_date of the subscription: - set qty_delivered = 1 for the delivered-policy product. - run _cron_recurring_create_invoice to generate a new invoice. Issue: When cron generates the invoice for the delivered product, the system links two payment transactions to this invoice Cause - On portal confirmation, only order-policy products are invoiced. - Because the delivered products are not invoiced upfront, the initial payment transaction gets linked only to part of the subscription. - Later, when 2nd invoice is generated by cron, the system reuses the original payment token and tries to apply payment for both (delivered + ordered) again. Solution - When confirming a subscription with portal payment, create the invoice for all products (order + delivered). - This way, the first payment covers the whole subscription and later invoices won’t get duplicate payments. Taskid-4250892
This change ensures payments made through the customer portal create invoices with the right context. It helps subscription-based sales and delivered products be invoiced correctly, while avoiding duplicate payments.
Original PR description
Version: - 18.0 On order confirmation, portal payments only invoice order-based products. Passing context `is_payment_transaction_invoice` allows sale_subscription to also handle delivered products correctly and avoid duplicate payments. related-PR: https://github.com/odoo/enterprise/pull/94009 Taskid-4250892 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When several product variant prices are updated, the system now keeps the “Update extra prices” action available until all related prices are properly synced. This prevents the button from disappearing too early and ensures all intended variant prices are carried through to sales orders.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update…
Versions -------- - 18.0+ Steps ----- 1. Have a product with multiple variants; 2. go to one of its attributes; 3. in the form, change the default extra price on multiple lines; 4. click on "Update extra prices"; 5. add the updated variants to a sale order. Issue ----- Only the line on which "Update extra prices" was clicked has been updated, even though the button disappeared on all lines after clicking it. Cause ----- The `_compute_default_extra_price_changed` method only compares the `default_extra_price` of the current record to its `_origin` value. Consequently, after saving the form, it will return `False`, even though only one attribute has been updated. Solution -------- Aside from checking whether the value changed on the form, also check whether any product template attribute value has a `price_extra` that's different from the product attribute value's `default_extra_price`. This way, clicking on "Update extra prices" once won't make the other update buttons disappear. opw-5240236
This change removes a unit test that depended on the wrong module setup and on Enterprise-only fields. It helps keep automated builds stable and avoids test failures caused by missing dependencies.
Original PR description
The unit test `test_can_reset_deferred_invoice()` has several issues. 1. It should be in the `account_audit_trail` module, as the test requires this module. [Unit test documentation: modules](https://www.odoo.com/documentation/19.0/developer/tutorials/unit_tests.html#modules). 2. The test references fields from the Enterprise module `account_accountant`, `account.move.line.deferred_start_date` and `account.move.line.deferred_end_date`. This causes build tests to fail. As such, the test should be removed now and replaced later if necessary. Fixes [PR 235223](https://github.com/odoo/odoo/pull/235223) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235813
This change moves a small portal-related customization out of the general rating area and into the dedicated portal rating module. It keeps the product structure cleaner and ensures the customization lives where its portal dependency belongs, reducing maintenance risk.
Original PR description
Since #234356, `_get_allowed_message_post_params` method of the `PortalChatter` has been overridden in the `rating` module. As the `rating` has no dependency on the portal, the current change moves this override to the `portal_rating` module.
This fix lets a user be added to a sales team when the team belongs to one of the companies the user is allowed to access, even if that is not the user’s default company. It removes an unnecessary restriction that was causing errors in multi-company setups and makes team membership behave more consistently.
Original PR description
### Steps to reproduce the issue: (Easier to reproduce client side with CRM installed) 0. Install crm 1. Create Second Company 2. Create New User with Current Company as Default Company and Second…
### Steps to reproduce the issue: (Easier to reproduce client side with CRM installed) 0. Install crm 1. Create Second Company 2. Create New User with Current Company as Default Company and Second Company in Allowed Companies 3. Create CRM Team belonging to Second Company 4. Add New User to Members of CRM Team 5. Receive error: > [New User] belongs to company [Current Company] and "Sales Team" (crm_team_id: [CRM Team]) belongs to another company. ### Explanation: `crm.team.member` is created when adding `res.users` to `crm.team.member_ids`. Contrary to `res.users`, a company_check is done when linking `crm.team` and `crm.team.member` together. `crm.team.member.company_id` is related to `user_id.company_id` and, in the case above, does not match `crm.team.company_id`, raising an error because of it. ### Fix reasoning: Removing restriction, as we want to avoid other multi-company issues by changing the behaviour. opw-4214192 --- @nd-dew note: Situation recap  So it was proposed to modify the field definition, seems to me that removing `check_company` from the field definition is a legal move, since it is an ORM level constraint (doesn't change db schema). However looking at the tests it seems like this is desired limitation. Note that https://github.com/odoo/odoo/pull/171079 introduced checking for allowed companies, but the **default company** still takes priority.
This update corrects the way product costs are computed in Point of Sale when a bill of materials depends on specific product variant values. As a result, POS orders now show the right cost per line for each variant, preventing inaccurate margins and reports.
Original PR description
When you create a product with atleast one variant that has 2 value, and create a BoM for this product that has 2 lines with each line having one of the two values, then create a POS order with one…
When you create a product with atleast one variant that has 2 value, and create a BoM for this product that has 2 lines with each line having one of the two values, then create a POS order with one unit of each variant, the cost of the first line not correctly computed. Steps to reproduce: ------------------- * Create a prodcut P with one attribute A that has two values A1 and A2 * Create a product C with no attribute and a cost of 10$ * Create a BoM for P with two lines: - Line 1: product C, quantity 1, only for attribute value A1 - Line 2: product C, quantity 2, only for attribute value A2 * Open a PoS session * Add Product P with attribute value A1 to the order * Add Product P with attribute value A2 to the order * Validate the order and close the session * Go to the order and check the cost of each line > Observation: The cost are not correct, they should be 10$ and 20$ Why the fix: ------------ Before this fix we were not taking the `bom_product_template_attribute_value_ids` into account when filtering the stock moves to consider for the cost computation. This value represent the attribute values that the product must have for this BoM line to be considered. opw-4765234 Forward-Port-Of: odoo/odoo#225014
This change prevents an error when validating a Sendcloud delivery for sales orders that include down payment invoice lines. It ensures only real product lines are used for customs price calculations, avoiding a validation failure for users.
Original PR description
Steps to reproduce ----- - Create a SO with a sendcloud delivery - Create an invoice for a down payment & confirm it - Go to the delivery and validate it > Traceback Cause ----- Creating a down…
Steps to reproduce ----- - Create a SO with a sendcloud delivery - Create an invoice for a down payment & confirm it - Go to the delivery and validate it > Traceback Cause ----- Creating a down payment adds lines to the SO https://github.com/odoo/odoo/blob/7bbfb207f8699973f8580ea18821f82b1a83e149/addons/sale/wizard/sale_make_invoice_advance.py#L163-L165 When we confirm the delivery, we retrieve the price of products for customs. https://github.com/odoo/enterprise/blob/f1a385e44ff9cb0e6a6c50c743762fb45329c957/delivery_sendcloud/models/sendcloud_service.py#L515-L520 To do this, we iterate over the SOL and skip lines where the product qty is 0 https://github.com/odoo/enterprise/blob/f1a385e44ff9cb0e6a6c50c743762fb45329c957/delivery_sendcloud/models/sendcloud_service.py#L525-L528 The problem is that the down payment SOL has no uom. This means that when we do `float_is_zero(line.product_uom_qty, precision_rounding=line.product_uom.rounding)` precision_rounding is `0.0`. So when `float_is_zero` calls `_float_check_precision` we go through https://github.com/odoo/odoo/blob/7bbfb207f8699973f8580ea18821f82b1a83e149/odoo/tools/float_utils.py#L33-L36 where the assert is false, creating the traceback. ----- Ticket: opw-5207574
This change stops users from creating the same purchase request for quotation more than once. It helps avoid duplicate quantities being added when the button is clicked again from another tab or by another user, keeping purchasing data accurate.
Original PR description
**Problem:** It's possible to click the "Create RFQ's" button more than once, as the user may have multiple tabs open or multiple users are viewing the same record. When this happens, the approval will create or add to an RFQ even if it already did, and this causes double the intended product quantities. **Solution:** The "Create RFQ's" button becomes hidden when purchase_order_count > 0 (i.e. there are linked POs) so we can perform this check within the button's method `action_create_purchase_orders` to prevent RFQ generation (or modification). opw-5227493 Forward-Port-Of: odoo/enterprise#99706
Purchase order emails now send users to the right company website when they click “View Quotation.” This fixes an issue where recipients could be taken to the default site instead of the website linked to the purchase order’s company, improving the accuracy of customer and supplier communications.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Host a server with demo data on localhost; 2. create & switch to a second company; 3. have a website linked to the second company; 4. set the website's domain to http://2.localhost:8069; 5. create a purchase order; 6. send order via email; 8. open mail via Settings / Technical / Email / Emails. Issue ----- The "View Quotation" button links to the default URL instead of the second company's website. Cause ----- The button added via `_notify_get_recipients_groups` only adds a relative URL, which then defaults to the database's base url when sent. Solution -------- Use an absolute URL, using the order's `get_base_url` method. opw-5035391 Forward-Port-Of: odoo/odoo#233255
This fix prevents an error in the Mexican Point of Sale flow when a customer asks for an invoice to be issued to the public. The system now correctly passes the needed invoice setting to the backend, so businesses can complete the sale even when the customer does not have a recognized ZIP code or country.
Original PR description
In the POS of a Mexican company, when requesting an invoice, the user is asked to set the invoice to public or not. If the customer does not have a recognized ZIP code or country, setting the invoice…
In the POS of a Mexican company, when requesting an invoice, the user
is asked to set the invoice to public or not. If the customer does not
have a recognized ZIP code or country, setting the invoice to public
**should not** raise an error, but it does. This is because the
`l10n_mx_edi_cfdi_to_public` field is not correctly updated in the ORM,
which leads to the UserError below being triggered, as
`l10n_mx_edi_cfdi_to_public` is always set to `False` if it's not
updated by its `_compute` method.
https://github.com/odoo/enterprise/blob/dd89c2c72039c9910cc0a303bca332f4103c08f6/l10n_mx_edi/models/account_move_send.py#L54-L55
The said field is not properly updated because it is a *compute field*.
Such fields are not transferred to the ORM because of the two following
conditions from the POS: \[[1](https://github.com/odoo/odoo/blob/5c2280d089f248dff67df980bee1ce6a4156f2c9/addons/point_of_sale/static/src/app/models/related_models.js#L205-L206), [2](https://github.com/odoo/odoo/blob/5c2280d089f248dff67df980bee1ce6a4156f2c9/addons/point_of_sale/static/src/app/models/related_models.js#L895-L896)\]
To minimize behavioral changes, the required field
(`l10n_mx_edi_cfdi_to_public`) is simply added at the end of the
serialization process.
Once this field is correctly shared with the ORM, the UserError is not
longer raised when the *Invoice to Public* field is set to "Yes"
in the POS.
### Steps to reproduce the initial error:
1. Install the following app and module:
- Point of Sale (`point_of_sale`)
- Mexican Localization for the Point of Sale (`l10n_mx_edi_pos`)
2. Set the company to a Mexican one (e.g., *ESCUELA KEMPER URGATE*)
3. Open the POS app
4. Open a register
5. Select a product and click *Add*
6. Click *Payment*
7. Set the Customer to a new customer with only a name
(no Country/ZIP Code)
- Click "Cash" to set the Remaining to 0
8. Toggle the *Invoice* button, set the *Invoice to Public* to *"Yes"*
and click *Ok*
9. Click *Validate*.
10. An error *"Invalid Operation, CFDI not set to Public"* appears.
opw-5171035This change fixes an issue where creating an invoice for an alternative upsell subscription order could fail, even after the customer payment had gone through. The missing date information is now carried over correctly, so invoices can be generated without errors.
Original PR description
Version - 17.0 Issue: - When creating and confirming an alternative sale order (SO) from an upsell order, attempting to generate an invoice would raise a deferred end date error - As a result, the…
Version - 17.0 Issue: - When creating and confirming an alternative sale order (SO) from an upsell order, attempting to generate an invoice would raise a deferred end date error - As a result, the invoice was not created, and even though the customer's payment succeeded, no invoice was issued. Steps to reproduce: - Create an upsell order of a subscription. - Click Create Alternative to generate an alternative SO. - Confirm the SO and click on Create Invoice to make the invoice - This will throw an error of defferred end date Cause: - The `next_invoice_date` was not copied from the previous upsell order to the new alternative SO. - Without this value, the deferred end date was incorrectly computed as today’s date - 1, triggering the error. Fix: - Copy the `next_invoice_date` from the previous upsell order to the new alternative SO to ensure proper deferred date computation. Impact: Invoices for alternative upsell sale orders can now be created successfully without errors. task-5241150 Forward-Port-Of: odoo/enterprise#98983
This fix prevents a payroll error that could interrupt payslip generation when some work entry information is missing. It makes the process more resilient so payroll can continue smoothly even when certain data is not available.
Original PR description
Bug: When generating payslips, there is a traceback with keyerror. Cause: We were getting info from a dict but keys could be not present. Fix: Use get instead, with a default value.
2 changes
Resolved issues and error corrections
This update keeps Odoo working with newer code-quality checks by adjusting a few internal patterns and test files. It also reduces false alarms during validation, helping teams run maintenance checks more smoothly and reliably.
Original PR description
- astroid 4 deprecates toplevel exports of nodes, thankfully that was never actually necessary so we can just import that unconditionally - remove support for pre-jammy pylint / astroid, specifically `astroid.nodes` was added in astroid 2.7.0 and `astroid.node_classes` deprecated then and removed in 3.0, this can affect Bullseye users as it shipped with astroid 2.5 - Astroid 4 changes `spec.Finder.find_module` in order to cache it (pylint-dev/astroid#2509), we can just make our method static for all versions as we don't need `self` anyway. - The mail test triggers `function-redefined` (E0102), fix it. - Skip the escpos script thing which triggers a bunch of `undefined-variable` (E0602) false positives.
This change removes repeated method definitions in a few enterprise modules. It does not add new user-facing features, but it helps keep the codebase cleaner and reduces the risk of maintenance issues later.
Original PR description
found by pylint 4