Daily updates from Odoo
Wednesday, November 19, 2025
259 changes
25 changes
Enhancements to existing features
The Point of Sale sales report now includes a more detailed view of payments grouped by payment method. This helps teams understand how customers pay and makes sales analysis and reconciliation easier.
Original PR description
In this commit: ----------- - Enhances the PoS sales report by adding detailed breakdowns of payments grouped by payment method. task-5184319 Forward-Port-Of: odoo/odoo#234486
The mail plugin now includes a way to identify the Odoo version it is connected to. This lets Odoo warn users when the new add-in is not supported on their version, avoiding confusion and failed usage.
Original PR description
Purpose ======= The new addin has been refactored and doesn't work with older Odoo version, and so we add an endpoint to be able to show a message if we don't support that Odoo version. Task-4727609 Forward-Port-Of: odoo/odoo#236286 Forward-Port-Of: odoo/odoo#236047
The IoT Box now turns its displayed build hash into a clickable link that opens the matching commit on GitHub. This makes it easier for teams to verify exactly which software version is running during support or troubleshooting.
Original PR description
To ease checking the HEAD commit on the IoT Box, we now compute the github url to the commit, and redirect to it clicking on the hash in the technical information tab. Forward-Port-Of: odoo/enterprise#99673 Forward-Port-Of: odoo/enterprise#99422
Resolved issues and error corrections
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
This fix ensures that when an invoice is converted into a credit note, or the other way around, the amounts keep the correct debit or credit placement when storno is enabled. This avoids incorrect negative values and helps accounting documents stay accurate during these conversions.
Original PR description
This commit fixes the amounts of move lines when converting from invoice to credit note and vice versa when storno is enabled. Previously, when converting from invoice/credit note, the amounts remained negative and switches from debit/credit. The quantities should remain in same debit/credit position and only change sign as I switch from invoice/credit note. task-5226311 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234027
This update corrects how the Point of Sale cash move popup creates its order so it includes the right configuration reference. As a result, receipt printing is less likely to fail or behave unexpectedly after cash movements.
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 fix restores the ability for customers to choose drop-off locations when a Sendcloud delivery service uses locker-based last-mile options. It ensures the map selection appears for both locker and service-point variants, so delivery methods behave as expected.
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 change fixes several WebSocket timeout issues so connections are handled more consistently. If the other side does not answer a close request in time, the connection is now properly terminated instead of lingering unexpectedly, improving reliability for users of the chat/bus system.
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
When a message template is duplicated, its attachments are now copied too instead of being shared between templates. This prevents accidental cross-updates and reduces the risk of attachment access issues when different rules apply to different templates. The copy behavior was also adjusted so user-provided values are preserved correctly.
Original PR description
Copying tmeplates should copy their attachments. Otherwise they are
shared, which means
* wrong res_id: ACL check on attachments relies on a specific
template, as res_model / res_id is used in access check;
* propagated changes: changing one attachment changes it on all
duplicated templates;
If custom rules on templates are implemented, this means notably
ACL issues when accessing attachments. It is not the case in standard
Odoo 17 as everyone can read templates but this notably changes in
future versions of Odoo.
While being there, also fix 'default' usage in copy override. User
given values should not be erased by default computation of name.
Task-5128863
Forward-Port-Of: odoo/odoo#234565
Forward-Port-Of: odoo/odoo#232877The import panel now recognizes CSV files whether their extension is written as .csv or .CSV. This avoids confusing differences in the import screen and makes file uploads behave more consistently for users.
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 ensures that salary offer links are created with a valid access token even when an offer is added manually from the list view. As a result, recipients can open the offer link reliably, including in private or incognito browsing sessions.
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 change removes a Windows IoT printing setting that was causing PDF labels to print with the wrong alignment on Zebra printers. It restores the expected label position and helps prevent misprinted labels in warehouse and shipping workflows.
Original PR description
Adding the argument "-dPDFFitPage" in the printer driver for the windows IoT broke the alignment when printing PDF labels on Zebra printers. Issue introduced in #232866 opw-5220275 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236041
Fixed an issue where deleted mail records were not consistently reflected in the interface. This makes the record status update automatically so users see accurate information without needing to refresh.
Original PR description
The `exists` function of mail records is not reactive. Indeed, it uses a symbol, stored on the proxy internal field which is not observed. This commit fixes the issue by storing it on the record and ensuring we write on the full proxy when the record is deleted. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236346 Forward-Port-Of: odoo/odoo#236042
This change makes the small dots on hatched calendar events easier to see, especially for unpublished items. It also moves the styling to the correct view layer so it works consistently in modules like Planning, even when Calendar is not installed.
Original PR description
When pills are hatched (unpublished event) in the calendar view (eg. planning) the `o_event_dot` is barely visible. Additionally the styling to display the dot as outlined on hatched event is wrongly scoped in `/calendar` with the calendar status styling. It should be in the view instead. Otherwise, for the planning module which doesn't depend on calendar, the styling is not applied if calendar is not installed, rendering the filled dot. task-3916768 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235978 Forward-Port-Of: odoo/odoo#235286
When users scan a different serial number for a kit component, the system now updates the existing reserved line instead of creating a duplicate one. This prevents incorrect backorder prompts and makes delivery processing smoother and more accurate.
Original PR description
### Issue: Scanning an unreserved lot of a kit component creates a new barcode line rather than updating the value of the initially reserved lot. As a result, the backorder porcess considers that…
### Issue:
Scanning an unreserved lot of a kit component creates a new barcode line rather than updating the value of the initially reserved lot. As a result, the backorder porcess considers that every unscanned yet initially reserved quantity is to backorder.
### Steps to reproduce:
- Create a kit product with a kit BOM:
- 1 x COMP (tracked by SN)
- Add two Serial numbers SN001 and SN002 in stock for the COMP product
- Create and confirm a delivery order for 1 unit of oyur kit product
- Go the barcode app to process your delivery
- Scan SN002
> A new line is created instead of updating the initial reservation
- Validate the delivery
#### > A backorder dialog opens proposing to update the unscanned reservation
### Cause of the issue:
Scanning a lot will first try to find a line to update, however, currently a line will only be found if the scanned lot has been reserved or if no particular lot has been reserved:
https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_model.js#L1659-L1661 https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_model.js#L743-L746 In particular, since no line is considered as valid, a new line is created. And, since this new line does not refer to any `move_id` while the existing one does, the move with the initial reservation will be backordered considering none of its demand was fulfilled: https://github.com/odoo/enterprise/blob/a1113eebf634302f7ceece612e7ee068c99781e4/stock_barcode/static/src/models/barcode_picking_model.js#L904-L921
### Fix:
In order to loosen the condition of lot override on barcode lines we add a check on the package and the location of the line in order to avoid use cases where the initial move line already contains info's that are proper to the initial lot.
opw-5100026
Forward-Port-Of: odoo/enterprise#99739
Forward-Port-Of: odoo/enterprise#98589This change prevents an error that could appear when reopening a point of sale register with the default Takeout preset selected. It ensures the system only creates a new order at the correct stage, so users can reopen registers without the traceback interrupting their work.
Original PR description
STEPS TO REPRODUCE: -------- 1. Set default preset as Takeout in configuration. 2. Open a register than Close the register. 3. Reopen the register. 4. Observe traceback. CAUSE: ----------------- LoginScreen created an order before the ProductScreen was loaded causing preset logic to access undefined order data. FIX: ----------------------------- Create a new order only when the selected screen is ProductScreen: Task-5237713
This fix makes the Replenishment list filters return accurate results when searching for items with a zero To Order value. It prevents records with a non-zero order quantity from being incorrectly included, which improves the reliability of inventory planning and filtering.
Original PR description
**Issue** In replenishment, filtering with `to_order = 0` does not correctly exclude records where `to_order != 0`. **Steps to reproduce** 1. Go to Inventory > Operations > Procurement >…
**Issue** In replenishment, filtering with `to_order = 0` does not correctly exclude records where `to_order != 0`. **Steps to reproduce** 1. Go to Inventory > Operations > Procurement > Replenishment 2. Create a replenishment with a forecast quantity smaller than the min and max quantity (without editing the To Order) 3. Apply a custom filter `to_order = 0` → Records with non-zero `to_order` are incorrectly included **Cause** `qty_to_order` was split into `qty_to_order_computed` and `qty_to_order_manual` in [this commit](https://github.com/odoo/odoo/commit/156bed3f430d706e13822bbd95d91c8dfd3ea42d#diff-0eb18a8d7773b5f99b402392188594178c3ba2004e4bcab26dbc84b1c8d7256a). In the [`_search_qty_to_order` method](https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/stock/models/stock_orderpoint.py#L338), all records with `qty_to_order_manual = 0` are included. Since `qty_to_order_manual` defaults to 0 when untouched by the user, this causes incorrect results. Additionally, [`to_order`](https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/stock/models/stock_orderpoint.py#L323) displays `qty_to_order_computed` if `qty_to_order_manual = 0`, creating inconsistency. **Solution** Fix the inconsistency by ignoring `qty_to_order_manual` when searching for zero `to_order` values. opw-5150643 Forward-Port-Of: odoo/odoo#234908
This update prevents a payroll calculation from failing when an employee’s contract start date is not set. It adds a safeguard so the system can continue processing instead of crashing on incomplete employee data.
Original PR description
The test_version_cron_update_no_fields from hr/tests/test_hr_employee.py didn't pass on runbot saas-18.4 due to the absence of a start date of contract leading to an error when trying to substract False to a datetime object. I added a verification in the concerned compute function in order to ensure the employee has a contract_date_start. If it's not the case, I set it to 0 as the compute method needs to compute the target field. Runbot error: 233590
Email-style messages in the chatter could show the read more/less control without its icon, making the button less clear for users. This update ensures the needed icon styling is available inside those messages so the control displays correctly.
Original PR description
Before this commit, when a message is of type "email" and contains parts are in foldable with more/less (like `<quote>`), the icon of the button for fold/unfold is missing. This happens because the icon is `.oi` and requires `odoo_ui_icons`. Message of type "email" have their content inside a shadow DOM, because we want to preserve the style of email inside the web client, at least in white theme. Shadow-DOM prevents the parent document to pass `odoo_ui_icons` thus the Shadow-DOM could not apply expected style on `.oi` icons. This commit fixes the issue by passing the required CSS as stylesheet to the shadow DOM, so that `.oi` icons are working inside the shadow DOM of message content of type "email". Forward-Port-Of: odoo/odoo#228741
This change prevents a crash that could happen when users press Backspace while editing the people assigned to a task in the kanban view. It improves stability so users can edit task assignments without seeing an error message or interruption.
Original PR description
How to reproduce: - Go to project tasks - Edit the list of people assigned to a task - Press backspace Current behavior: Traceback Expected behavior: No traceback task-5189783 Forward-Port-Of: odoo/odoo#235489
This fix lets users be added to a Sales Team when that team belongs to one of the companies they are allowed to access, even if it is not their default company. It removes an unnecessary blocker in multi-company setups and makes team management behave more consistently for business users.
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. Forward-Port-Of: odoo/odoo#189441
17 changes
Enhancements to existing features
The mail plugin now includes a way to identify the Odoo version it is connecting to. This lets Odoo display a clear message when the add-in is used with an older, unsupported version instead of failing without explanation.
Original PR description
Purpose ======= The new addin has been refactored and doesn't work with older Odoo version, and so we add an endpoint to be able to show a message if we don't support that Odoo version. Task-4727609 Forward-Port-Of: odoo/odoo#236286 Forward-Port-Of: odoo/odoo#236047
Invoice delivery to customers and government EDI systems is now deferred until after the payment transaction is fully committed. This reduces the risk of invoices being sent and then lost due to a rollback, helping keep Odoo records aligned with external government numbering and customer communications.
Original PR description
When the payment transactions trigger the creation of invoices and then the sending of those invoices by mail and through the EDI to the government, any concurrent update can make that entire process…
When the payment transactions trigger the creation of invoices and then the sending of those invoices by mail and through the EDI to the government, any concurrent update can make that entire process fail all at once. This mainly happens when the user himself is paying through the portal as this will create the invoice from the payment. When invoices are sent to the government however, we want to be sure that when sent, it gets updated in Odoo as well, so we are aware what is happening. The problem we got is that invoice 1 is sent to the government (l10n_in_edi) as number 01 and then that transaction is totally rolled back that the invoice is not even there anymore, it risks that the government's numbers and your numbers do not correspond anymore. So, we should avoid that that invoice can be sent when before there is a concurrent update (on payment transaction in this case) waiting for destroying it when committing. So, the simple idea would be to only do the invoice sending through a post commit. As we are locking the invoice itself for the sending to the government that should be enough to avoid the invoice sending for not being registered in Odoo. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
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
This fix prevents imported bank statement lines from being lost when a validation error occurs during automatic reconciliation. Instead of cancelling the whole import, the system now keeps the lines so users can review and reconcile them manually afterward.
Original PR description
### Issue: When importing a CSV file with bank statements, if an error is raised during the reconciliation, the creation of the bank statement lines is roll backed. ### Steps to reproduce: - Install…
### Issue: When importing a CSV file with bank statements, if an error is raised during the reconciliation, the creation of the bank statement lines is roll backed. ### Steps to reproduce: - Install "account_bank_statement_import_csv" - In the bank journal configuration: - Set the "Outstantding Receipts accounts" of "Manual payments" to a "Bank" account - Set the "Outstantding Payments accounts" of "Manual payments" to the same "Bank" account - Create a new transaction for $333.0 for example - Find its Journal Entry and change its reference to 'testref' - have a CSV file like this: ``` label, amount testref,333 ``` - Import this file - Make sure label is linked to label and amount to amount - Import - An error shows, no lines are imported ### Cause: On import, we try to auto reconcile the lines using `_cron_try_auto_reconcile_statement_lines` ([here](https://github.com/odoo/enterprise/blob/843a17367525c80653d37ecdd9d87434d3e92454/account_bank_statement_import_csv/wizard/account_bank_statement_import_csv.py#L146)). If an error occurs during the reconciliation, we call `self.env.cr.rollback()` [here](https://github.com/odoo/enterprise/blob/843a17367525c80653d37ecdd9d87434d3e92454/account_accountant/models/account_bank_statement.py#L190-L192). This rollback cancels the transaction, including the creation of the statement lines. ### Solution: If the error raised is a `UserError` then we don't roll back and just ignore it. This causes no issues as we caught all exceptions to always continue the reconciliation with the next batch. For UserErrors we should let the user reconcile manually afterward. Also, as the rollback can undo the creation of `st_lines`, we add `if st_lines.exists():` before writing on the variable. Test is not possible as we don't roll back during tests. opw-5138855
This fix ensures that when a single payment settles multiple invoices, each invoice is linked to the correct foreign-exchange adjustment. It prevents exchange differences from being assigned to the wrong invoice, improving the accuracy of accounting records and invoice reconciliation.
Original PR description
# How to reproduce the issue: - Create two currency rates: one for today and one for the day before. - Create two invoices with different `amount_total`, both using the rate from yesterday. - Create…
# How to reproduce the issue: - Create two currency rates: one for today and one for the day before. - Create two invoices with different `amount_total`, both using the rate from yesterday. - Create a group payment dated today. Check the generated payment, its journal entry, and the reconciled items. Two exchange moves are created — one for each invoice. However, on the invoices themselves, only one of those exchange moves is associated with both invoices. Since commit 5420e40ff337080912edf7414257e03853be026a, the logic that associates exchange moves to `account.partial.reconcile` records was changed. It links an exchange move to a partial if any of its reconciled lines match either the partial's `debit_move_id` or `credit_move_id`. In a group payment scenario: - Two partials are created (one per invoice). - Each has a different `debit_move_id` (the invoice lines) but shares the same `credit_move_id` (the single payment line). - As a result, both partials match the same exchange move via the shared credit line — leading to incorrect assignment. opw-5147281 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change makes event markers easier to see when an event is displayed with a hatched style, such as unpublished items. It also moves the styling to the correct place so the display stays consistent even when the calendar app is not installed, which helps modules like Planning show the right appearance.
Original PR description
When pills are hatched (unpublished event) in the calendar view (eg. planning) the `o_event_dot` is barely visible. Additionally the styling to display the dot as outlined on hatched event is wrongly scoped in `/calendar` with the calendar status styling. It should be in the view instead. Otherwise, for the planning module which doesn't depend on calendar, the styling is not applied if calendar is not installed, rendering the filled dot. task-3916768 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235978 Forward-Port-Of: odoo/odoo#235286
Fixed an issue where filtering replenishment records by zero quantity could still show items that actually needed to be ordered. This makes the list view match the displayed order quantity, so users can trust their filters and review the right items.
Original PR description
**Issue** In replenishment, filtering with `to_order = 0` does not correctly exclude records where `to_order != 0`. **Steps to reproduce** 1. Go to Inventory > Operations > Procurement >…
**Issue** In replenishment, filtering with `to_order = 0` does not correctly exclude records where `to_order != 0`. **Steps to reproduce** 1. Go to Inventory > Operations > Procurement > Replenishment 2. Create a replenishment with a forecast quantity smaller than the min and max quantity (without editing the To Order) 3. Apply a custom filter `to_order = 0` → Records with non-zero `to_order` are incorrectly included **Cause** `qty_to_order` was split into `qty_to_order_computed` and `qty_to_order_manual` in [this commit](https://github.com/odoo/odoo/commit/156bed3f430d706e13822bbd95d91c8dfd3ea42d#diff-0eb18a8d7773b5f99b402392188594178c3ba2004e4bcab26dbc84b1c8d7256a). In the [`_search_qty_to_order` method](https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/stock/models/stock_orderpoint.py#L338), all records with `qty_to_order_manual = 0` are included. Since `qty_to_order_manual` defaults to 0 when untouched by the user, this causes incorrect results. Additionally, [`to_order`](https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/stock/models/stock_orderpoint.py#L323) displays `qty_to_order_computed` if `qty_to_order_manual = 0`, creating inconsistency. **Solution** Fix the inconsistency by ignoring `qty_to_order_manual` when searching for zero `to_order` values. opw-5150643 Forward-Port-Of: odoo/odoo#234908
This update corrects a printing setting in the Windows IoT driver that caused PDF labels to be resized incorrectly. As a result, labels should now print with the proper alignment on Zebra printers.
Original PR description
Adding the argument "-dPDFFitPage" in the printer driver for the windows IoT broke the alignment when printing PDF labels on Zebra printers. Issue introduced in #232866 opw-5220275 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236041
This update fixes a problem where some Sendcloud delivery services did not offer drop-off point selection, even when they should have. Users can now choose locker or service point delivery locations correctly on the map, improving checkout options for affected carriers.
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 how invoice and credit note amounts are handled when storno is enabled. When users switch between an invoice and a refund, the values now stay in the proper debit or credit position and only the sign changes, preventing incorrect amounts.
Original PR description
This commit fixes the amounts of move lines when converting from invoice to credit note and vice versa when storno is enabled. Previously, when converting from invoice/credit note, the amounts remained negative and switches from debit/credit. The quantities should remain in same debit/credit position and only change sign as I switch from invoice/credit note. task-5226311 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234027
This change fixes WebSocket timeout handling so stalled or unresponsive connections are detected and closed properly. It improves reliability by making sure the system does not leave broken connections open, which helps prevent communication issues for users.
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
Italian POS receipts can now be reprinted from past orders correctly. Previously, selecting an older order could print the last receipt instead, which caused confusion and incorrect customer copies.
Original PR description
before this commit, when trying to reprint a past order it would not work. Instead it would print the last order no matter what order is selected. Steps to reproduce: 1. setup an DB with an italian…
before this commit, when trying to reprint a past order it would not work. Instead it would print the last order no matter what order is selected. Steps to reproduce: 1. setup an DB with an italian POS 2. make 2 sales with a different product (easier tracking) 3. open the "orders" view 4. try to reprint the ticket of the firt order result: the receipt of the second order is printed the reason for this is that we were using the printer's built in command "printDuplicateReceipt" which is inteded for printing the very last receipt. With this commit, we changed the behavior and invoke another printer command. That command is meant to reprint any receipt, based on the provided reference. After this commit, trying to print any past receipt will print that exact receipt. IMPORTANT NOTE: In theory, the printer command can reprint any number of receipts. We decide that we will only use it to reprint the one receipt selected by the user. This moves the complexity of parsing date strings and ranges to the command component and therefore will keep the rest of the code cleaner. opw-5008702 opw-4882480 Forward-Port-Of: odoo/enterprise#96122
When users type @ in a channel, the suggested people to mention are now limited to the channel’s authorized group. This prevents people from seeing or selecting mentions for users outside the intended group, improving privacy and access control in discussions.
Original PR description
Before this commit it would be possible to mention any partner in a discuss channel with an Authorized Group (group_public_id). Steps to reproduce: 1. Log as Mitchell Admin 2. Open Administrator channel 3. Write "@" in composer to get mentions 4. Observe having non-administrator partners This happens because we don't send the `group_public_id` record client side (`_field_store_repr` replaces it with the group name), and as such the suggestion service does not correctly filter for partners in the Authorized Group. This commit fixes the issue by correctly sending the `group_public_id` field of the channel. task-5258925 Forward-Port-Of: odoo/odoo#235478
This change makes Stripe-related payment errors visible to cashiers in the Point of Sale instead of being hidden. It helps users understand why a card payment failed and reduces confusion during checkout.
Original PR description
Before this commit: =================== Previously, Stripe-related RPC calls used `silentCall`, which suppresses backend errors and prevents them from being displayed in the POS UI. As a result, users were unable to see important validation or API failure messages coming from the server After this commit: ====================== Use `call` instead of `silentCall`. Using `call` allows backend exceptions and validation errors to be propagated to the POS frontend, ensuring that the user receives clear feedback when a Stripe request fails. Task-4976972
4 changes
New functionality added to Odoo
This update adds a new EC Sales List report for Finnish accounting users, including the export file needed to submit it. It helps businesses produce the required EU sales reporting more easily and consistently.
Original PR description
The aim of this commit is adding the Finnish EC Sales List report. task-5126664 Forward-Port-Of: odoo/enterprise#95901
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#97217This fix ensures Sendcloud delivery methods that use lockers or service points can correctly offer drop-off point selection to customers. It resolves cases where the map was not shown because these delivery options were not being recognized properly.
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
Italian Point of Sale receipts can now be reprinted for the specific past order the user selected. Previously, the system always printed the last receipt, which could cause confusion and the wrong document to be given to customers or used for records.
Original PR description
before this commit, when trying to reprint a past order it would not work. Instead it would print the last order no matter what order is selected. Steps to reproduce: 1. setup an DB with an italian…
before this commit, when trying to reprint a past order it would not work. Instead it would print the last order no matter what order is selected. Steps to reproduce: 1. setup an DB with an italian POS 2. make 2 sales with a different product (easier tracking) 3. open the "orders" view 4. try to reprint the ticket of the firt order result: the receipt of the second order is printed the reason for this is that we were using the printer's built in command "printDuplicateReceipt" which is inteded for printing the very last receipt. With this commit, we changed the behavior and invoke another printer command. That command is meant to reprint any receipt, based on the provided reference. After this commit, trying to print any past receipt will print that exact receipt. IMPORTANT NOTE: In theory, the printer command can reprint any number of receipts. We decide that we will only use it to reprint the one receipt selected by the user. This moves the complexity of parsing date strings and ranges to the command component and therefore will keep the rest of the code cleaner. opw-5008702 opw-4882480 Forward-Port-Of: odoo/enterprise#96122
29 changes
Enhancements to existing features
The mail plugin can now detect which Odoo version is in use. This lets it display a clear message when the version is not supported, helping users understand why the add-in may not work.
Original PR description
Purpose ======= The new addin has been refactored and doesn't work with older Odoo version, and so we add an endpoint to be able to show a message if we don't support that Odoo version. Task-4727609 Forward-Port-Of: odoo/odoo#236286 Forward-Port-Of: odoo/odoo#236047
The Point of Sale sales report now includes a clearer breakdown of payments by method, making it easier to see how customers paid. This helps businesses review sales patterns and reconcile reports more quickly.
Original PR description
In this commit: ----------- - Enhances the PoS sales report by adding detailed breakdowns of payments grouped by payment method. task-5184319 Forward-Port-Of: odoo/odoo#234486
The IoT Box technical information now includes a clickable link from the image version hash to the exact GitHub commit. This makes it easier and faster to verify which software version is running on the device when troubleshooting or checking updates.
Original PR description
To ease checking the HEAD commit on the IoT Box, we now compute the github url to the commit, and redirect to it clicking on the hash in the technical information tab. Forward-Port-Of: odoo/enterprise#99673 Forward-Port-Of: odoo/enterprise#99422
The self-order attribute selection page now shows a clear “Required” badge next to mandatory attributes. This makes it easier for customers to spot what must be selected and reduces the chance of missing required options.
Original PR description
PURPOSE: --------- - Help users to easily identify which attributes are required in the POS self-order attribute selection page. Before this commit: ------ - Required attributes had no badge or clear visual indication. After this commit: ---------- - Added a Required badge next to attribute names so users can quickly identify and select them. Task-5079571
Resolved issues and error corrections
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
This update prevents the website editor from crashing when a saved AI live chat snippet is added again from the custom blocks list. It improves the editing experience by making saved snippets reusable without error.
Original PR description
Steps to reproduce: ------------------------- 1. Install Website and AI modules. 2. Open the website editor. 3. From the Intro block, search for the AI snippet and add the snippet contains 'Need…
Steps to reproduce:
-------------------------
1. Install Website and AI modules.
2. Open the website editor.
3. From the Intro block, search for the AI snippet and add the snippet contains 'Need Help?'.
4. Click on the added block, then click the Save icon from the Style tab.
5. Save the snippet
6. Go to Blocks → Custom Blocks and add the saved snippet.
Observation:
-------------------------
A traceback is raised:
```
TypeError: Cannot read properties of null (reading 'remove')
at AILivechatOptionPlugin.onSnippetDropped
```
Issue:
-------------------------
The `onSnippetDropped` method
https://github.com/odoo/enterprise/blob/bb3699cc112acb3ec545d3aa5f3d8f7263a5dac6/ai_website_livechat/static/src/website/plugins/ai_livechat_option_plugin.js#L39-L51 executes every time a snippet is dropped into the layout. When the snippet is first added, the method removes the `<div>` with class `s_ai_livechat_preview`. Upon saving, the snippet is stored without that `div`. When re-adding the saved snippet from custom tab, the method runs again but fails since the `s_ai_livechat_preview` element no longer exists, resulting in the traceback.
Solution:
-------------------------
Added the optional chaining operator to safely remove the `s_ai_livechat_preview` div only when it exists.
opw-5227072This fix corrects how point of sale order line amounts are sent to the backend. When a product quantity is greater than 1, the tax-excluded line total now reflects the full line amount instead of just the unit price, which also ensures sales reports show the right totals.
Original PR description
Steps to reproduce ------------------ 1. Create a product with price 1, no need to add taxes, and add it to PoS 2. In PoS, select this product, and set the quantity to 2, the price is 2 as expected 3. Finalize the order 4. In the backend, open this order and observe that the "Tax Excl." for that line shows $1 instead of $2. While "Tax Incl." shows $2 as expected. The client has reproduced this issue in a different way, by printing the sales report for that order, he found out that the total is 1 instead of 2. Why it's happening ------------------ This issue was introduced in 9538698f13d5763b49b00f4c06a1a2afc0d6b39e. We are setting the field `price_subtotal` to the unit price of the product, and not to the actual price per line, i.e. we're ignoring the quantity!! The Fix ------- We now set the `price_subtotal` to `priceExcl` which takes into account the quantity on that line. opw-5242022
This update corrects several problems with totals shown in list views, especially for monetary and mixed-currency records. It also fixes a display alignment issue so summary values appear in the right place in lists.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change adds a database index to a key link used by the Vietnam Viettel e-invoicing feature. It helps Odoo find related records faster, improving performance and reducing delays in processes that rely on these invoice templates.
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)` Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects how the point of sale control pad styles and layout are applied, so the buttons and payment options display consistently. It also removes an unnecessary empty section that could interfere with the layout, improving the reliability of the checkout screen.
Original PR description
In this commit: ------------------- - Removed conditional CSS logic, as the styles are required in all cases. - Updated the condition to display the third row with fast payment methods, preventing issues caused by unnecessary blank div. task: 5246635
This change corrects how currency rates are calculated in the Uruguay electronic invoicing process. Rates are now always converted relative to the Uruguayan Peso, ensuring consistent results regardless of the company’s own currency.
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 adjusts the website builder test setup so it works reliably in Firefox. It prevents a test-only browser behavior from blocking the builder tests, helping ensure the website editing experience can be validated consistently across browsers.
Original PR description
In the website builder test suite, Chrome doesn't load the initial iframe (we load a dummy iframe instead) and never goes through `preparePublicRootReady` from the `WebsiteBuilderClientAction`. On the contrary, Firefox does load the initial iframe. We already have a partial fix for it in the html_builder test helpers (see `originalIframeLoaded`), but it stopped working at some point. As Firefox loads the iframe and goes through `preparePublicRootReady`, it re-assigns `this.publicRootReady` to a deferred that is never resolved in tests, which prevents any Hoot builder test from working. Solution: completely override `preparePublicRootReady` with an empty method in tests. task-5266212 Forward-Port-Of: odoo/odoo#235830
This fix restores the ability to edit the Stock report’s “On Hand” field in Studio without errors. It prevents a duplicate field setting from breaking the Studio side panel, so users can customize the view normally again.
Original PR description
### Steps to reproduce: - Go to Inventory > Reporting > Stock - Toggle studio and enable debug mode - Click on the "On Hand" column #### > UncaughtPromiseError > OwlError > Uncaught Promise: > Got…
### Steps to reproduce: - Go to Inventory > Reporting > Stock - Toggle studio and enable debug mode - Click on the "On Hand" column #### > UncaughtPromiseError > OwlError > Uncaught Promise: > Got duplicate key in t-foreach: /list[1]/field[x]_hide_trailing_zeros #### Note: We enabled debug mode to raise template rendering issues but without debug mode the template of the left studio panel is simply not rendered. ### Cause of the issue: The `qty_available` displayed in the `product.product` list view https://github.com/odoo/odoo/blob/12ec5d2d9cd93fffb10bf10326cf3cde7707ea0c/addons/stock/views/product_views.xml#L574-L575 is associated with a `stock_action_field` widget. However, since e4c51ad8a6da17339923875de7fa303544b717e1 this widget has become an hybrid entity able to support both the float and the monetary fields: https://github.com/odoo/odoo/blob/12ec5d2d9cd93fffb10bf10326cf3cde7707ea0c/addons/stock/static/src/fields/stock_action_field.js#L12-L22 The issue is due to the fact that the template of sudio component `TypeWidgetProperties` can not be rendered for our `qty_avaialble` field as it receives the `hide_trailing_zeros` boolean attribute twice in this `t-foreach`: https://github.com/odoo/enterprise/blob/4ba22ee091938d382fb79ef386b4761e4e15479a/web_studio/static/src/client_action/view_editor/interactive_editor/properties/type_widget_properties/type_widget_properties.xml#L23-L25 This happens because the `stock_action_field` adds it twice in its supportedOptions: https://github.com/odoo/odoo/blob/12ec5d2d9cd93fffb10bf10326cf3cde7707ea0c/addons/stock/static/src/fields/stock_action_field.js#L55-L67 once because of the `floatField.supportedOptions`: https://github.com/odoo/odoo/blob/12ec5d2d9cd93fffb10bf10326cf3cde7707ea0c/addons/web/static/src/views/fields/float/float_field.js#L119-L124 and once because of the `monetaryField.supportedOptions`: https://github.com/odoo/odoo/blob/12ec5d2d9cd93fffb10bf10326cf3cde7707ea0c/addons/web/static/src/views/fields/monetary/monetary_field.js#L113-L118 opw-5188594 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The shop editor now correctly previews 1:1 product thumbnails before saving. This makes image ratio changes easier to verify and helps ensure the chosen layout is applied as expected across shop-related pages.
Original PR description
Before this PR, the 1:1 aspect ratio option in the editor (/shop) showed no preview on hover and didn't apply correctly until saving. It treated 1:1 as a special case that removed all classes instead of applying an explicit one. This PR fixes the issue by adding explicit o_wsale_products_opt_thumb_1_1 class support. task-5123229 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Alternative Products section on the website now displays clean product names instead of including internal reference codes for certain products. This makes the product cards match the main product page and improves the customer shopping experience.
Original PR description
**Steps to reproduce:** 1. Install eCommerce. 2. Open a product > Sales Tab > Alternative Products 3. Add products with an internal reference (default_code) and Attributes. 4. Go to website > scroll…
**Steps to reproduce:**
1. Install eCommerce.
2. Open a product > Sales Tab > Alternative Products
3. Add products with an internal reference (default_code) and Attributes.
4. Go to website > scroll down to the alternative products section.
**Issue:**
- The "Alternative Products" snippet displays the product's internal reference
in the title.
- This occurs only for products with attributes and variants(attribute_line_ids)
- The behavior is inconsistent with the main product page, where only the
product name is shown
Cause :
- The QWeb template was accessing the product name through values['data']['_record'] (which is a product.template)
whose display_name includes internal reference (e.g., [E-COM06] Corner Desk Right Sit).
This occurs for products that have attribute_line_ids.
https://github.com/odoo/odoo/blob/f0a34badefd432e9c2ab36acaf018d20d0e342fe/addons/website_sale/data/product_snippet_template_data.xml#L17-L20
<img width="1920" height="458" alt="image" src="https://github.com/user-attachments/assets/c3088149-b6c8-4cd7-8db4-129f0282a09d" />
- However, values['data'] already contains a clean display_name
(e.g., Corner Desk Right Sit) i.e. as expected.
**Solution:**
- Updated the QWeb template to use the correct field from the prepared data:
`t-out="data.get('display_name') or product.display_name"`
- This ensures that the title displays a clean product name consistent with the
main product page, without the internal reference
**opw-5122632**The user group selection field now correctly displays placeholder entries that were previously ignored. This makes it possible to represent a "no group" choice as intended, improving accuracy when configuring user privileges.
Original PR description
Before this commit, privilege's placeholders were ignored in the res_users_group_ids field widget. Those placeholders were supposed to be added in the selection and act as a "no group" value. This commit fixes the issue. task~5275552 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures that package weight is calculated correctly when packages contain other packages. The package’s own base weight is now applied at every level, so shipping weights and related logistics calculations are more accurate.
Original PR description
When using multi-level packages, when the weight of the package is computed, the base weight of the package type is only counted for the top-level package, not for the children packages. Task-5166120 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix makes mail record existence checks update correctly when a record is deleted. It ensures the interface reacts immediately to changes instead of showing outdated information.
Original PR description
The `exists` function of mail records is not reactive. Indeed, it uses a symbol, stored on the proxy internal field which is not observed. This commit fixes the issue by storing it on the record and ensuring we write on the full proxy when the record is deleted. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236346 Forward-Port-Of: odoo/odoo#236042
The Recruitment app now displays the job position email field correctly in the kanban view. This small visual fix improves readability and makes the job card layout look consistent after adding an email alias.
Original PR description
Steps to reproduce: --------------------------- 1. Install the Recruitment app with demo data. 2. In Settings, add an Email Alias for the company. 3. Open the Recruitment app. 4. Click the Configure…
Steps to reproduce: --------------------------- 1. Install the Recruitment app with demo data. 2. In Settings, add an Email Alias for the company. 3. Open the Recruitment app. 4. Click the Configure button on the job position kanban card. 5. In the Job Position form view, add an email alias. 6. Use the breadcrumbs to navigate back to the job positions. Observation: --------------------------- The email field for the job position is misaligned in the kanban card. Issue: --------------------------- The `div` containing the email is missing a `justify-content-*` class https://github.com/odoo/odoo/blob/5ab45d45073463495e517aca9fd061415a73e893/addons/hr_recruitment/views/hr_job_views.xml#L77 Solution: --------------------------- Add the missing `justify-content-between` class to align the email properly. Before: <img width="1909" height="749" alt="before" src="https://github.com/user-attachments/assets/51790c71-f30d-4402-ae24-a5ccfb30ff9a" /> After: <img width="1914" height="697" alt="after" src="https://github.com/user-attachments/assets/711f83f6-208e-44c3-83e2-8b736c697a9d" /> opw-5246587
18 changes
Enhancements to existing features
Financial reports now calculate much faster by reusing previously computed account totals instead of repeating the same work for every line. This reduces waiting time significantly for large reports while keeping the results the same.
Original PR description
### Issue Large financial reports are slow to compute due to repeated re-aggregation of account_move_line balances for each formula, even when most formulas share the same base domain (usually…
### Issue
Large financial reports are slow to compute due to repeated re-aggregation of account_move_line balances for each formula, even when most formulas share the same base domain (usually filtered by account_id fields).
### Analysis
Each report line formula independently aggregates balances from account_move_line, even when their domains only differ on account_id-related fields such as account_id.account_type or account_id.non_trade.
This leads to redundant scanning and aggregation of the same dataset multiple times within a single report execution.
### Solution
Introduce a lightweight in-memory caching layer for aggregated balances by account_id, stored in self.env.cr.cache.
For each (options, date_scope) pair:
The report engine now computes once the mapping
{account_id: {'amt': total_balance, 'count_aml_lines': count}}.
This mapping is stored in the cursor cache and reused across all formulas whose domains filter exclusively on account_id fields.
A small domain transformation step allows AML domains based on account_id.* fields to be evaluated directly against the cached account aggregates.
This approach avoids redundant SQL aggregation, remains fully read-only (no database writes), and is safe for execution on read replicas.
### Benchmarks
Profiling get_report_information_readonly on different reports. Database has ~11.6 million account_move_lines, 305 account_accounts, and 16 account_types
| Report Name | Before | After | % Speed Up |
| --- |---|---|---|
| Balance Sheet | 35s | 6.2s | ~550% |
| Profit and Loss | 7.2 | 2.1 | ~300% |
| Cash Flow Statement | 1.5s | 0.4s | ~300% |
| Executive Summary | 24s | 6.3 | ~400% |
### References
opw-5130725Resolved issues and error corrections
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.
The calendar day view no longer cuts off event titles on mobile devices. This makes it easier for users to quickly understand their schedule without opening each event.
Original PR description
Before this commit, when the user goes to a calendar view in day to check what he have to do. He cannot see the event title properly in his mobile phone since the title is truncated. This commit makes sure the event title is not truncated to clearly see the whole event title. Before the fix: <img width="1172" height="802" alt="image" src="https://github.com/user-attachments/assets/f85a4a03-89a3-48c8-bda7-38e72854ce1f" /> After the fix: <img width="1179" height="808" alt="image" src="https://github.com/user-attachments/assets/7b0b31ba-10f5-412b-837b-8399c78c5bac" />
When storno is enabled, converting an invoice to a credit note or back now keeps the amounts in the correct debit or credit position. This prevents incorrect negative values and ensures the converted document stays financially accurate.
Original PR description
This commit fixes the amounts of move lines when converting from invoice to credit note and vice versa when storno is enabled. Previously, when converting from invoice/credit note, the amounts remained negative and switches from debit/credit. The quantities should remain in same debit/credit position and only change sign as I switch from invoice/credit note. task-5226311 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234027
This change fixes a visual issue where card images could show white edges when a hover animation was applied. It keeps the image filling its card properly, improving the look of website content and avoiding unwanted gaps.
Original PR description
Step to reproduce: 1. Open website 2. Click edit button and drop s_three_columns snippet 3. Click image and change animation option into hover 4. Some extra white space shown. Before this commit: Applying a hover animation on card images caused the `object-fit` property to unintentionally switch from `cover` to `contain`, resulting in visible white borders around the image.This happened because of the `geo_square` shape, which is automatically injected when a hover effect is applied and no user shape is chosen. This behavior was intentionally introduced in PR [1]. After this commit: Now cropped images use object-fit: contain to preserve the visible properly. and after stretch option apply it can take cover of this container. so his ensures the image fully covers its container without leaving any white gaps. [1]:https://github.com/odoo/odoo/pull/119197 task:4875770
This change corrects how invoice taxes are recalculated when a foreign currency rate is set directly on the invoice. It ensures the total amount stays consistent with the configured global tax rounding method, avoiding small but visible balance differences between similar invoices.
Original PR description
- Set the tax rounding method to `'global'` in the settings. - Create an invoice in a foreign currency with: - Quantity: `0.80` - Unit Price: `894.34` - Currency rate set on the invoice: `1 / 1189.5` - This results in a journal entry balance of **851,051.57**. - Now set the currency rate directly on the currency instead. - Duplicate the invoice: the journal entry balance becomes **851,053.94**. The issue arises because _sync_tax_lines, triggered when setting the currency rate directly on the invoice, was computing the journal entry balance on a per-line basis, even though the tax rounding method was configured as global. opw-5012817 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update makes the payment black box more resilient when it returns an invalid reply or a negative acknowledgment. It now follows the documented behavior by waiting up to 1.5 seconds and retrying up to three times, which helps reduce failed operations caused by temporary device issues.
Original PR description
Following documentation, max timeout should be 1.5s and we should retry 3 times on every bb NACK/invalid data.
This update adjusts an automated test so it follows the same path a user would take in the interface. That ensures the system correctly detects and reports an invalid event product setup, preventing false test failures and improving confidence in the validation rule.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Have a minimal database with `event_product` installed; 2. run `:TestEventProduct.test_ensure_event_service_tracking`. Issue ----- > FAIL:…
Versions -------- - 18.0+ Steps ----- 1. Have a minimal database with `event_product` installed; 2. run `:TestEventProduct.test_ensure_event_service_tracking`. Issue ----- > FAIL: TestEventProduct.test_ensure_event_service_tracking > AssertionError: ValidationError not raised Cause ----- The test works as expected with `sale_project` installed due to a `write` override of `product.product`, setting the `service_tracking` to 'no' if `type` is no longer 'service': https://github.com/odoo/odoo/blob/dc57ea4d306f8745d37f2c5d2c3d3fa4bcaf7253/addons/sale_project/models/product_product.py#L25-L30 This change still occurs without `sale_project` installed, but via the `_compute_service_tracking` method defined in `product`: https://github.com/odoo/odoo/blob/dc57ea4d306f8745d37f2c5d2c3d3fa4bcaf7253/addons/product/models/product_template.py#L181-L183 As this value is set via a compute method instead of `write`, the `_check_event_ticket_service_tracking` method isn't triggered, and no error is raised. Solution -------- Simulate a front-end flow by changing the `type` to 'consu' on a product form. This way, the constraint method does get triggered as expected. runbot-234024
This change reverts a printer setting that caused PDF labels to print with the wrong alignment on Zebra printers used with Windows IoT. It restores the expected label positioning so printed labels remain accurate and usable.
Original PR description
Adding the argument "-dPDFFitPage" in the printer driver for the windows IoT broke the alignment when printing PDF labels on Zebra printers. Issue introduced in #232866 opw-5220275 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236041
This update prevents an error when closing or canceling a helpdesk ticket in teams that have no working hours set for SLA policies. It ensures the closing process only checks working hours when that setting is actually configured, avoiding unexpected interruptions for users.
Original PR description
> **The issue:** When you go to a helpdesk's team settings -> SLA Policies -> Working hours, set the working hours to empty and then disable SLA Policies and save. After that if you try to move a ticket in the same team to done or canceled you will receive an exception. **Cause:** The part of the code causing the issue is supposed to only run if a Working Hours policy is set. **Fix:** Changed the section of the code to only run when Working Hours is set. opw-5120962 > Forward-Port-Of: odoo/enterprise#96546
This fix prevents Studio from crashing when a user adds a new Selection field option without entering any text. The “Add Selection” action now safely ignores empty input, improving reliability while configuring fields.
Original PR description
**Before this commit:** When a user added a new Selection field and clicked the “Add Selection” :white_check_mark: button without entering any value, a `Client Error: (Cannot read properties of undefined (reading 'trim'))` was raised, resulting in a crash of the Studio interface. **After this commit:** Clicking the “Add Selection” :white_check_mark: button with an empty input no longer triggers an error. task-5159376 Forward-Port-Of: odoo/enterprise#98767
This change fixes an error that could appear when opening Documents after a related CRM record had been deleted. It ensures orphaned upload requests are handled safely, so users no longer see a traceback in this situation.
Original PR description
Steps to reproduce: - Install crm and documents - Go to CRM → Activity Types - Set a folder in the Upload Document activity - Create a CRM lead and schedule an upload document activity - Delete the created lead - Open the Documents module Issue: - A traceback occurs because web_read tries to access values_by_id[record.id], as the upload request document remains in the database after its related activity is deleted. Solution: - fix the recompute of res_name and set it to False, avoiding MissingError opw-5080182
This update fixes an issue where the message composer could fail when no message was attached yet. As a result, suggestions now load reliably and the composer no longer runs into this error in that case.
Original PR description
This commit solves a runbot issue created by the debounced nature of the suggestion fetch. A composer could not have a message associated with it and was therefore failing to find the related thread. Now, the thread is set to undefined in that case since we do not need the result anyway. fixes-runbot-230311 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Website discussion bubbles are now shifted out of the way while editing, so they no longer cover the page builder. This makes it easier for users to select and edit snippets, especially when multiple conversations are open at once.
Original PR description
Before this commit, discuss bubbles would appear on top of the editor when editing a website. I was therefore be difficult to select some snippets, especially when the user had a lot of conversations at the same time and he wanted to keep the discuss bubbles visible. This commit shift the discuss bubbles on edit to solve the issue. task-4266898
This update makes Odoo compatible with the latest code quality checker versions, preventing false errors during development and testing. It also cleans up a few test and hardware-related scripts so automated checks run more reliably across supported environments.
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. Forward-Port-Of: odoo/odoo#236258
This change cleans up duplicated methods in a few areas of the system. It does not add new business functionality, but it helps keep the codebase easier to maintain and reduces the risk of inconsistent behavior later.
Original PR description
found by pylint 4 Forward-Port-Of: odoo/enterprise#99809
7 changes
Enhancements to existing features
This update makes delivery lookup by lot much faster by changing how the system gathers the needed information. It reduces delays for users working with many lots, especially in large stock operations, so screens and processes complete more quickly.
Original PR description
### Description: This refactoring replaces the recursive calculation in `_find_delivery_ids_by_lot` with an iterative process. This change significantly reduces the amount of database queries by prefetching and batching all required lines in a single pass, and it also eliminates the overhead caused by repeated recursive function calls. ### Benchmark: | Total Lots | Before | After | |------------|--------|--------| | 69 | 1 sec | 106 ms | | 1152 | 1 min | 5 sec | ### Reference: opw-5096599
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
Odoo now uses the updated official code for Odisha in India, replacing the older code. This keeps contact and sales information aligned with current government standards and helps avoid mismatches when creating customer records and sales orders.
Original PR description
**Steps to reproduce:** 1. Install the `Contacts` module. 2. Go to Contacts > Create a new contact. 3. Select country India, and state Odisha. 4. Create a sales order using the newly created contact. **Issue:** As per [Government of India](https://www.iso.org/obp/ui/#iso:code:3166:IN), the state code was officially changed from "OR" to "OD" in 2023. However, Odoo still uses the outdated code. <img width="407" height="163" alt="image" src="https://github.com/user-attachments/assets/1631a831-f455-4a51-886f-7e4ed691add0" /> **Solution:** Update the name of the state from "OR" to "OD" in state records. **opw-4935633**
Blog post paragraphs will now inherit the font size set in the website theme. This makes blog content match the site’s design settings and keeps formatting consistent across the page.
Original PR description
Previously, changing the paragraph font size in the theme (Website > Edit > Theme > Paragraph > Font Size) did not affected the paragraphs within blog posts. This was because blog post paragraphs used a static font size, overriding the theme's setting. This PR removes the overriding style, allowing blog post paragraphs to inherit the font size defined in the theme. task-4167716
This change prevents an empty “Column” options panel from appearing when editing media list snippets on the website. It also stops the edit overlay from covering items when there are no relevant settings to show, making the editing experience cleaner and less confusing.
Original PR description
Steps to reproduce [A]: - Go to website ("edit" mode) > Add a new "Media List" snippet. - Select one of the snippet items > An empty "Column" options section will appear on the sidebar and an overlay…
Steps to reproduce [A]:
- Go to website ("edit" mode) > Add a new "Media List" snippet.
- Select one of the snippet items > An empty "Column" options section
will appear on the sidebar and an overlay will be covering the item.
After [1], grid layout options were updated to be able to set grid items
padding individually, the new snippet option used for that
(see: `GridColumns`) is targeting every `.row > div` and uses the widget
visibility code to be sure that the option is available only in "Grid"
mode, which leads to the behaviour described above.
There is already an implementation to prevent sections with hidden
widgets from being visible (see: `updateOptionsUIVisibility()`) and
adapt the overlay accordingly, but it only handles specific situations:
[B]- The implementation on [2] (used to move the switchable views to a
`SnippetOption`) led to a situation where an empty "Page Options" editor
was visible on every page.
[C]- This visible section issue from [B] was fixed (see [3]) by hiding
the `snippetEditor` if none of its options are visible (including the
`we-top-button-group` options).
[D]- Even with a hidden "Page Options" `SnippetEditor`, its overlay will
always be visible (with an empty options tab) when the `<main/>` element
is clicked. The code from [4] fixed a specific situation of the issue:
The code will hide the overlay only if there are no options at all
(`customize$Elements === null`), which is the case for `SwitchableViews`
(e.g. for a `SnippetEditor` with parent editors, we only need to hide
the overlay if its `$optionsSection` is empty).
The goal of this commit is to fix the behaviour described in [A] in two
simple steps:
- Allow hiding the `snippetEditor` even if it contains visible
`we-top-button-group` options, since an editor with no
`we-customizeblock-option` is enough to prevent its visibility (also,
the fix in [3] was specifically introduced to hide the "Page Options"
editors).
- Generalize the check from [4] to hide the overlay of every editor with
an empty options section.
[1]: https://github.com/odoo/odoo/commit/11418cc6f0afcc8e14869f4f38ae0d6d462ac712
[2]: https://github.com/odoo/odoo/commit/69af7dcfeb3ff95c40b00ef0cc7c5c0e4021f9d2
[3]: https://github.com/odoo/odoo/commit/39d073ccafddf4b3fbe9ec9f5f11849d77c9bdaa
[4]: https://github.com/odoo/odoo/commit/fccac358dae7092c8c7cd90ba1ee89c712bc86e9
task-3658153This fix prevents WhatsApp setup from failing when it references an archived user account, such as an inactive administrator account. It helps ensure the module installs smoothly without requiring someone to reactivate a user first.
Original PR description
The current constraint on `notify_user_ids` fails if the linked user is archived, as `active_test=True` (default) prevents reading archived records. This issue is notable on SaaS when installing WhatsApp since the default template phone record's user is the admin account, so if the admin user is archived it will cause the install to error out. By explicitly disabling `active_test` in the constraint, we ensure that archived users can still be read during this validation, preventing false negatives and allowing the module to be installed without requiring admin reactivation. opw-5006472