Daily updates from Odoo
Wednesday, July 30, 2025
37 changes · saas-18.3
Resolved issues and error corrections
This update brings the spreadsheet component to the latest version and fixes several user-facing issues. Users should see safer handling of cancelled formatting changes, better pivot calculations for date/time fields, and more accurate data validation suggestions.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/2a7178a06 [REL] 18.3.14 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/2a7178a06 [REL] 18.3.14 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/34fdd1eb3 [FIX] cf: do not override changes on cancel [Task: 4609695](https://www.odoo.com/odoo/2328/tasks/4609695) https://github.com/odoo/o-spreadsheet/commit/4a1547b56 [FIX] pivot: support SUM and AVG aggregators for datetime fields [Task: 4945217](https://www.odoo.com/odoo/2328/tasks/4945217) https://github.com/odoo/o-spreadsheet/commit/f23bfa0ca [FIX] data validation: handle cell format in auto-complete [Task: 4865661](https://www.odoo.com/odoo/2328/tasks/4865661) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
This fix prevents customers from completing checkout with products that have been archived or unpublished after being added to their cart. When a product is archived, it is removed from existing website carts so orders cannot be placed for unavailable items.
Original PR description
Fix issue where customers could complete purchases of products that where archived or unpublished after being added to cart but before checkout completion. => Step to reproduce bug : - Install website_sale. - Add a product to the cart. - (In an other window) archive the product. - finish the buy from the cart. (don't reload the cart or the product will be gone) => Cause: The bug originate from: https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/addons/website_sale/controllers/main.py#L1781-L1793 There is no check up during the last part of the transaction to verify if the product is still available. => Fix: Erase from the product from all cart when it's archived opw-4829872 Forward-Port-Of: odoo/odoo#220162 Forward-Port-Of: odoo/odoo#213656
This fix prevents Odoo Inventory from creating duplicate stock quantity records when validating transfers that move entire packages. It helps keep package and product quantities accurate, reducing the risk of incorrect inventory availability or fulfillment issues.
Original PR description
### Steps to reproduce: - In the settings enable "packages" and Multi-Step Routes - Create a 3 storable products: P1, P2, P3 - Put on hand quantities for each of them: - 1 x P1 in PACK001 in stock -…
### Steps to reproduce:
- In the settings enable "packages" and Multi-Step Routes
- Create a 3 storable products: P1, P2, P3
- Put on hand quantities for each of them:
- 1 x P1 in PACK001 in stock
- 1 x P2 in PACK001 in stock
- 1 x P3 in PACK002 in stock
- Create and confirm a delivery with 3 moves:
- 1 x P1
- 1 x P2
- 1 x P3
- Go to Inventory > Configuration > Warehouse Management > Operation type
- Modify internal transfers to "Move entire packages"
- Create and confirm and internal transfer for PACK001 from stock to the sublocation stock/shelf1
- Mark the package as done and validate the transfer
#### > You end up with 2 quants for PACK002 in stock
### Cause of the issue:
When validating the internal transfer for PACK001, we launch an `_action_done` on the moves lines of the internal transfer. In particular, during this action done, a `quant_cache` will be set for to fetch and use the quants for P1 and P2:
https://github.com/odoo/odoo/blob/cb1c761777e84d96f82c4f754586795509ce1b3d/addons/stock/models/stock_move_line.py#L679-L681 https://github.com/odoo/odoo/blob/cb1c761777e84d96f82c4f754586795509ce1b3d/addons/stock/models/stock_quant.py#L933-L949 This cache is correctly use in order to update our move lines during the `synchronize_quant` that will follow:
https://github.com/odoo/odoo/blob/cb1c761777e84d96f82c4f754586795509ce1b3d/addons/stock/models/stock_move_line.py#L684-L692 However, they are not in the `_free_reservation` because this call will reassign the move line and then `_check_entire_pack` for the entire picking:
https://github.com/odoo/odoo/blob/cb1c761777e84d96f82c4f754586795509ce1b3d/addons/stock/models/stock_move.py#L1980-L1981 In particular, it will update the reservation for the move related to P3. But, since the `quant_cache` is taken from the context and did not change it can not find the quants related to P3 and a new quant will be created in addition to the already existing one: https://github.com/odoo/odoo/blob/82639728f2bcb4e7786f120de2aeba3f5fbab209/addons/stock/models/stock_quant.py#L1055 https://github.com/odoo/odoo/blob/82639728f2bcb4e7786f120de2aeba3f5fbab209/addons/stock/models/stock_quant.py#L1101
opw-4922032
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#219049The Philippine BIR 2307 spreadsheet export now includes the partner ZIP code and uses the correct tax description for the nature of payment. It also formats company and individual taxpayer names more accurately, helping businesses produce cleaner and more compliant withholding tax reports.
Original PR description
The BIR 2307 XLS export was missing the `ZIP_code` and incorrectly showing the `nature` of payment from the invoice line instead of the tax description. In this commit: --- - Added a new column `zip_code` to show the ZIP from the `partner`. - Changed the `nature` column to use the `tax-description` instead of `product-name`. - Displaying `companyName` only when the commercial partner is a company. - Displaying `surName`, `firstName`, and `middleName` only when the commercial partner is an individual. enterprise-PR- odoo/enterprise#91120 task-4880921 Forward-Port-Of: odoo/odoo#220946 Forward-Port-Of: odoo/odoo#214940
Automatic invoice emails for website purchases now use the proper system context, so they are sent from the assigned salesperson instead of appearing to come from the customer or admin. This prevents confusing duplicate notifications to the administrator and improves customer-facing invoice communication.
Original PR description
**Steps to reproduce**: 1. Enable automatic invoicing `Settings -> Sales -> Invoicing -> Automatic Invoice` 2. Configure a payment provider like `Stripe` (not demo) 3. Open the website in an…
**Steps to reproduce**: 1. Enable automatic invoicing `Settings -> Sales -> Invoicing -> Automatic Invoice` 2. Configure a payment provider like `Stripe` (not demo) 3. Open the website in an incognito browser and log in as a portal user 4. Add a product to cart and checkout with the portal user's delivery address 5. Complete payment using test card credentials 6. Navigate to the created invoice in Sales **Observed behavior:** The invoice email is sent to both the portal user (customer) and the system admin, appearing as if the email is sent "from admin to admin" instead of from the assigned salesperson. **Root cause:** When automatic invoicing is enabled and a portal user completes a website purchase, the `_send_invoice()` method uses `self.env['account.move.send']` which runs in the portal user context. The portal user is selected as author, and the email template uses `partner_to` so it is also selected as partner. While sending mail, this triggers the `mail_notify_author` context. Additionally, due to the portal user not having proper email sending permissions, the system adds admin as fallback. As a result, emails are sent by admin, and because of `mail_notify_author`, mail is also sent to admin. **Solution:** Changed `self.env['account.move.send']` to `tx.env['account.move.send']` in the `_send_invoice()` method. Since `tx` is created with `SUPERUSER_ID` context, this ensures the invoice sending runs with proper system permissions and uses the transaction's context instead of the portal user's context. This ensures emails are authored by the correct salesperson, not the portal user. opw-4760568 Forward-Port-Of: odoo/odoo#221064 Forward-Port-Of: odoo/odoo#220504
The Peru localization data now spells Huancayo correctly, removing an accidental space in the city name. This helps users select and display the correct city name in Peruvian address records and related documents.
Original PR description
The Huancayo has an extra space in the name. Instead of Huancayo it is written Hua ncayo in the csv file. opw-4947526 Forward-Port-Of: odoo/odoo#220835 Forward-Port-Of: odoo/odoo#219888
This fix restores missing product identification information in electronic invoices and corrects a bank-branch field to match Peppol BIS3 rules. It helps ensure generated UBL invoices validate correctly and reduces the risk of rejected electronic invoices.
Original PR description
### [FIX] account_edi_ubl_cii: Add SellerItemIdentification and add tests Before the UBL refactor, the `SellerItemIdentification` node was populated with the product code. We restore this behaviour. In addition, the refactor added the `StandardItemIdentification` node without specifying the `schemeID` (which is required by the schematron), then commit f46c10f03e59e8 added `schemeID="0160"` This commit adds tests to enforce this behaviour. task-none ### [FIX] account_edi_ubl_cii: BIS3 rm FinancialInstitutionBranch/schemeID In BIS3, the `FinancialInstitutionBranch` node should not specify the `schemeID` property. https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/UBL-CR-655/ This was correct before the UBL refactor but was messed up by the refactor. task-none Forward-Port-Of: odoo/odoo#219924
This fixes an issue where unsupported devices connected to an IoT box caused repeated device updates to be sent every few seconds. The change reduces unnecessary database requests and log noise without changing normal device behavior.
Original PR description
In the forward port of odoo/odoo#218109, a bug was introduced where if an unsupported device is connected, the device list is always detected as being changed, so the IoT box sends devices to the database every 3 seconds. This doesn't cause any problems other than spamming the logs and the DB with requests, but should be fixed regardless. After this commit, the unsupported devices are taken into account correctly when detecting device changes. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Improves how Odoo recognizes Microsoft Office documents uploaded through the Documents flow, especially older Word, Excel, and PowerPoint files and newer Excel files. This prevents valid Office files from being renamed incorrectly, such as changing an Excel spreadsheet into a ZIP file, reducing confusion for portal users and document managers.
Original PR description
## [FIX] core: python3-magic vs .doc/.xls/.ppt [python3-magic](https://packages.ubuntu.com/noble/python3-magic)/[python-magic](pypi.org/project/python-magic) (apt/pip) is a frontend for…
## [FIX] core: python3-magic vs .doc/.xls/.ppt [python3-magic](https://packages.ubuntu.com/noble/python3-magic)/[python-magic](pypi.org/project/python-magic) (apt/pip) is a frontend for [libmagic](https://manned.org/man/ubuntu-noble/magic) the library that can introspect files to determine their types. The Documents app makes heavy usage of our mimetypes utilities to scan and fix the extensions of files uploaded by portal users. Everytime a portal user uploads a `.doc`/`.xls`/`.ppt` file, python3-magic is gonna guess the mimetypes `application/x-ole-storage` or `application/CDFV2` which are the mimetypes of the generic file format that Microsoft Office was using until 2006. The problem is that there is no specific extension for those two mimetypes as Microsoft was using the same file format for many of its office applications. In this work we enrich python3-magic's detection with our own, which is able to tell different `application/x-ole-storage` and `application/CDFV2` files apart. **Please note**: Excel files are detected only when the entire file is present. Excel files uploaded via the Documents app are not detected because Documents only `guess_mimetype` on the first 1kiB of the document. We also added a condition to keep the .doc/.xls/.ppt extension in case the generic `application/x-ole-storage` or `application/CDFV2` mimetype is guessed. Before it was emitting a warning due to the unknown extension. ## [FIX] core: python3-magic vs new (2025) .xlsx files [python3-magic](https://packages.ubuntu.com/noble/python3-magic)/[python-magic](pypi.org/project/python-magic) (apt/pip) is a frontend for [libmagic](https://manned.org/man/ubuntu-noble/magic) the library that can introspect files to determine their types. The Documents app makes heavy usage of our mimetypes utilities to scan and fix the extensions of files uploaded by portal users. Sometypes when portal user uploads a `.xlsx` file, python3-magic fails to detect the Microsoft Excel 2007+ (OOXML) mimetype and instead guesses a generic `application/zip`. Technically this is not wrong, OOXML files (like Java JAR and Python Weels) are using the zip format. This is quite strange because python3-magic is able to work with `.xlsx` files. I'm guessing that Microsoft deployed a new version of Excel and that magic doesn't correctly guess the new (2025) `.xlsx` files. Using a hex editor, the old (from our unittests) and new (from a 2025 support ticket) seem similar: OOXML files, deflate compression, same files present. They are a bit different, in the old the `[Content_Types.xml]` file comes last, in the new it comes first. The zip headers are different too, the old uses zip Data Descriptors, the new doesn't. The problem is that the Documents app uses the guessed mimetype to "fix" the extension of the uploaded file. So the portal-user's `file.xlsx` gets wrongly rewritten to `file.zip`. We first used an approach similar to the previous commit[^1], to use our own detection of OOXML files. It works great in base where we run the detection on whole files. However it doesn't work for the Documents app because it attempts to guess the mimetype only reading the first 1kiB of the uploaded file. A first PR odoo#213647 suggested to change Documents to load the whole file first, and then run `guess_mimetype`, but was rejected. In this work, we made so we don't fix the extension of zip-like files should the guessed mimetype be application/zip. [^1]: [FIX] core: python3-magic vs .doc/.xls/.ppt opw-4607156 opw-4753670 Forward-Port-Of: odoo/odoo#220644
This fixes a mail thread issue where access and thread existence information could be missing when a request contained an empty list. Users should see more consistent mail and discussion behavior when opening or interacting with records.
Original PR description
Even if the request is an empty array, access (and existence of thread) should be sent. How to reproduce: https://github.com/odoo/odoo/pull/220605 Forward-Port-Of: odoo/odoo#220924 Forward-Port-Of: odoo/odoo#220774
Users can now update progress bar values reliably in Firefox. This fixes an inconsistency where edits saved in some browsers but not in Firefox, improving data entry reliability in list views.
Original PR description
Before this commit, the input of the progressbar field couldn't be updated on firefox. It works on the other browsers by chance. In the list renderer, we call `preventDefault` on enter keydown. The event is first catch by the list renderer. This call is enough to prevent "change" event to trigger but on chromium browsers it is actually triggered (but should not). The progressbar field catches it and saves the new value. On firefox, the "change" event is never triggered. The commit fixes the input by using the input field hook to make it behave correctly. task-4881210 Forward-Port-Of: odoo/odoo#218860 Forward-Port-Of: odoo/odoo#215770
Editing existing website links with relative addresses now keeps those addresses unchanged instead of converting them into full website URLs. This prevents unintended link changes when users open and apply the link editor in the website builder.
Original PR description
This PR is backport of https://github.com/odoo/odoo/pull/216832 and https://github.com/odoo/odoo/pull/218587 Steps to reproduce: - Open website builder - Click on a link with a relative URL (there is /contactus in footer) - Bug: the url shown is an absolute url (https://.../contactus) - Click "Edit Link" (one of the icons) - Click "Apply" - Bug: the url in the dom has changed (it saved the absolute url) The link popover used HTMLAnchorElement.href to get the url. This getter returns an absolute url even if the href attribute is a relative url. task-4890293 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix updates an automated website tour so it correctly detects when a scroll animation has finished. It helps keep website testing reliable and prevents false failures during quality checks.
Original PR description
## Version 18.0+ ## Issue The tour `snippet_popup_and_animations` times out when trying to wait for the last column to become "not animated and hidden". This happens because the element never…
## Version 18.0+ ## Issue The tour `snippet_popup_and_animations` times out when trying to wait for the last column to become "not animated and hidden". This happens because the element never actually becomes `hidden` after the scroll-triggered animation ends — it remains in the DOM and visible. ## Cause Commit 7e85f88214b6b57db87a6c1964286f0b7813f6ff attempted to fix a selector that was always true by adding `:hidden`, assuming the element would be hidden once the scroll animation completed. But since the element’s visibility is never changed via `display: none` or `visibility: hidden`, the `:hidden` condition never matches, blocking the tour. ## Fix Remove the `:hidden` pseudo-class from the trigger. Instead, wait for the `.o_animating` class to be removed (indicating the end of the animation), then: - Add a short delay to ensure animation processing is complete. - Check that the element is outside of the viewport (scrolled out). - Verify that `animation-delay` is approximately 0. runbot-227077 Forward-Port-Of: odoo/odoo#219979 Forward-Port-Of: odoo/odoo#215567
The calendar now keeps the "more" event popover fully opaque, even on non-working days. This prevents events behind the popover from showing through, improving readability and the overall scheduling experience.
Original PR description
This commit resolves a visual issue with the FullCalendar "more" popover, where its background could appear partially transparent—causing events behind it to show through and creating a poor user experience. The problem was introduced with the update to FullCalendar v6.1.10, which applies cell-related classes (like o_calendar_disabled) to the popover. On non-working days, this class applies a semi-transparent grey background, affecting the popover's readability. The fix ensures that the popover background remains opaque in this specific case, restoring proper visual separation from underlying content. task-4916099 Forward-Port-Of: odoo/odoo#218877
Users can now create project tasks with one, two, or three priority stars directly from the shortcut text. This fixes a limitation in quick task creation, making it faster to capture the intended priority without editing the task afterward.
Original PR description
Issue:
------------
Currently, when creating a task using the shortcut, it is not possible to set multiple priority levels.
Fix:
---------
With this commit, users will be able to set multiple priority levels (up to 3) when creating a task using the shortcut syntax.
Supported priority levels:
-----------------
- 1 star: task1 @admin #high !
- 2 stars: task1 @admin #high !!
- 3 stars: task1 @admin #high !!!
Steps to Reproduce:
--------------
- Install the Project module.
- Go to the Project app.
- In the Kanban view, create a task using the shortcut.
- Paste the following into the task name field:
`task1 @admin #high !!!`
task-3935867The Spanish Modelo 390 VAT report now avoids counting vendor refunds twice and includes all relevant manual adjustment lines in the total. This improves the accuracy of annual VAT reporting for Spanish localization users.
Original PR description
This commit addresses two issues in the Mod 390 report:
---
1. Vendor refunds were being reported twice:
- Once correctly via the tax grid.
- And again incorrectly through the cross-formula on lines 639 and 62, which are meant for special manual adjustments only.
➤ Fix: Lines 639 and 62 are now treated as external values, making them
editable and excluding them from automatic computation.
2. Line 64 was missing part of the total:
- It did not include balances from lines 661 and 62, resulting in an incomplete total.
➤ Fix: Updated the computation of line 64 to sum all relevant manual lines.
---
task-4972473
Forward-Port-Of: odoo/odoo#220730This fix reduces memory usage when changing account codes in the Chart of Accounts. It prevents large accounting databases from running out of memory during these updates, making the process more reliable for finance teams.
Original PR description
Description ----------- Writing a new code for an account in the mappings of a COA will retrigger expensive recomputations for all moves linked to the accounts via its lines. This can lead to quick…
Description ----------- Writing a new code for an account in the mappings of a COA will retrigger expensive recomputations for all moves linked to the accounts via its lines. This can lead to quick exhaustion of the memory budget for the processing of the request (2 GiB by default). The commit odoo/odoo@8c5bfff4667ac2f8ec349278dda77d980242aae1 was supposed to address this issue by disabling the fields prefetcher when either 'code' or 'account_type' are being written to, but there is a logical oversight in the condition. ```py prefetch_fields=any(field in vals for field in ['code', 'account_type']) ``` Means "activate prefetch if it exists a field 'code' or 'account_type' in the vals". This is the opposite of what was intended, if the fields *do not* exist, only then we prefetch. So we can just negate the condition. Benchmark --------- For a database where updating the code of an account in the COA mapping, which impacts ~370K account.move and their related ~1.56M account.move.line, saving the new code memory took: | | Before | After | |-------------------|----------|---------| | Peak Memory Usage | 2.78 GiB | 879 MiB | Reference --------- opw-4951670 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220849
This fix prevents an error when a user clears the employee field while creating a time off allocation measured in hours. It keeps the allocation form stable and avoids an unexpected crash during normal data entry.
Original PR description
A traceback occurs when a user removes the Employee field while creating a time off allocation record. **To reproduce the issue:** 1) Install the `Time Off` module. 2) Create a new time off…
A traceback occurs when a user removes the Employee field while creating a time off allocation record. **To reproduce the issue:** 1) Install the `Time Off` module. 2) Create a new time off allocation record. 3) Navigate to the `Related Time Off Type` record. 4) Change the `Take Time Off in` option to Hours. 5) Return to the allocation and remove the Employee field. **Error:** ``` ZeroDivisionError: float division by zero ``` **Cause:** - When the Employee field is cleared, the `_compute_number_of_days` method is triggered. - Since the allocation_unit is set to Hours, this method attempts to calculate `number_of_days` using `_get_hours_per_day`. https://github.com/odoo/odoo/blob/96d4bd7911ba122610fd42c009da0a8e565e50ec/addons/hr_holidays/models/hr_leave_allocation.py#L256-L262 - However, when `employee_id` is missing, `_get_hours_per_day` returns 0, resulting in a division by zero. https://github.com/odoo/odoo/blob/96d4bd7911ba122610fd42c009da0a8e565e50ec/addons/hr_holidays/models/hr_employee.py#L140-L143 **Solution:** Since the employee_id is a required field in allocation, Adding an extra check for employee_id will resolve this issue. opw-4937893 Forward-Port-Of: odoo/odoo#219403
The custom filter builder now limits image and other binary fields to checks for whether a value exists or not. This prevents users from saving unsupported filters that could trigger errors when working with records such as products.
Original PR description
The system encountered an error when users attempted to apply invalid filters on `binary fields` (e.g., `image_1024`). The error occurs when operators like 'is in' with empty string values ('') are…
The system encountered an error when users attempted to apply invalid filters on `binary fields` (e.g., `image_1024`). The error occurs when operators like 'is in' with empty string values ('') are used, as binary fields are stored As attachments only support existence checks.
**Steps to produce:-**
1. Add a filter like `[('image_1024', 'in', [])]` in the custom filter where the image exists(eg, Products) and save.
2. Error triggered.
**Error:-**
`Binary field 'Image 1024' stored in attachment: ignore image_1024 in [''] .`
**Solution:-**
- The `web` client's filter operator selection logic has been updated to restrict options for `binary` field types. Now, for binary fields, only the `is set` (`!= False`) and `is not set` (`= False`) operators will be available in the custom filter builder.
**Sentry - 6236134077**
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#220997
Forward-Port-Of: odoo/odoo#213608French-company invoice forms no longer crash when users remove the Delivery Address field through Studio. The change safely skips address-specific layout logic when that field is not present, helping users customize invoice screens without errors.
Original PR description
The system will crash with an error when we try to remove the field 'Delivery Address' from the invoice view while in 'fr company'. **Steps to Produce:-** - Install `l10n_fr` and `web_studio` with…
The system will crash with an error when we try to remove the field 'Delivery Address' from the invoice view while in 'fr company'. **Steps to Produce:-** - Install `l10n_fr` and `web_studio` with demo data. - Switch to `FR Company`. - Go to `Invoicing > Customers > Invoices`. - Open any invoice > Toggle studio > Click on `Delivery Address` > and then click on `REMOVE FROM VIEW`. - Observe the error. **Error:-** `IndexError: list index out of range` **Root Cause:-** - At [1], the `_get_view` method unconditionally expects the `partner_shipping_id` field to be present in the invoice form view. - It performs an `xpath` search for the field and immediately attempts to access the first element of the result list. **Solution:-** - Now, if the `partner_shipping_id` field exists in the view, then the logic proceeds as before. If it's not found, the code block is simply skipped. [1]: https://github.com/odoo/odoo/blob/044833804c9e10048ec10d7e982c98c4f33f4cf4/addons/l10n_fr_invoice_addr/models/account_move.py#L16 **sentry-6746543069** I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218974
This fixes a visual alignment issue in form views where some input fields displayed extra padding and misaligned borders when placed next to nested input fields. The change improves consistency and polish in forms without affecting business logic or user workflows.
Original PR description
Inside form views when an input is displayed next to an other which contains nested `o_input`, the border is misaligned. This is due to a duplication of the `o_input` style in `form_controller.scss` which overrides the rule handling nested `o_input` in `fields.scss` resulting in 2x the necessary padding. [task-4974502](https://www.odoo.com/web#id=4974502&cids=1&menu_id=4720&action=333&active_id=1695&model=project.task&view_type=form) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#220751
Fixes an employee presence display issue where changing today's work location could still show as unspecified before saving. The displayed location now refreshes when daily homeworking fields change, giving managers and employees more accurate presence information.
Original PR description
Step to reproduce:
------------------
* Go on Employees
* Click on one Employee
* Change a today worklocation "office" (don't save, you need to have the little cloud)
* Hover over hr presence icon
This title will be "unspecified" and not "office".
Reason:
--------
name_work_location_display is computed but doesn't depends of daily worklocation field (monday_worklocation, tuesday...)
Solution:
---------
Depends of these daily worklocation field
task-4948488
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#220359
Forward-Port-Of: odoo/odoo#219222Companies in Greece and Ireland with valid VAT numbers will now correctly see the Intra-Community Valid checkbox for VIES verification. This fixes a country-code mismatch so eligible businesses are properly recognized for EU VAT validation.
Original PR description
Current behavior before PR: - Intra-Community Valid checkbox (for vies verification) was not showing for Greece and Ireland companies with valid VAT number. This was because Greece ISO is GR and Ireland ISO in IX, but their VAT start with EL and IE Desired behavior after PR is merged: - Checkbox is shown despite differences between ISO and beginning of VAT Link to task : - https://www.odoo.com/odoo/project/967/tasks/4575784 Forward-Port-Of: odoo/odoo#201630
Employees can now place or update lunch orders when the cost is within their allowed overdraft limit. This prevents valid orders from being blocked and keeps the Lunch wallet rules aligned with the company’s configured settings.
Original PR description
**Current Behavior:** The overdraft amount (`lunch_minimum_threshold`) is configured in Lunch settings is ignored when employees create or update lunch orders. As a result, even if the total order…
**Current Behavior:** The overdraft amount (`lunch_minimum_threshold`) is configured in Lunch settings is ignored when employees create or update lunch orders. As a result, even if the total order amount is within the allowed overdraft limit, the system blocks the action. **Steps to Reproduce:** 1) Install the Lunch module. 2) Set an overdraft amount in the Lunch settings. 3) Ensure an employee's wallet balance is less than a desired order total. 4) Attempt to create a lunch order or increase product quantity such that the total is more than the wallet balance but within the wallet + overdraft amount. **Issue:** - In both the product view (`_compute_display_add_button`) and the dashboard (`canAdd` logic), the wallet balance is calculated using `get_wallet_balance(include_config=False)`. - This call excludes the overdraft threshold, causing incorrect warnings and hiding of the `Add to Cart` or `+` buttons. **Solution:** - Remove the explicit `include_config=False` argument so the default True is used, ensuring the overdraft is included. - In the dashboard logic, enhance _make_info() to return a wallet_with_config key using get_wallet_balance(include_config=True) and update the canAdd check to use this value. opw-4782564 Forward-Port-Of: odoo/odoo#217532
Products with GST rates other than 5% now include the required packaged-good tag when syncing to Swiggy and Zomato. This helps ensure product information is classified correctly on delivery platforms and reduces sync inconsistencies.
Original PR description
*: pos_urban_piper_swiggy, pos_urban_piper_zomato Before this commit: --- - Products with GST != 5% were not receiving the `packaged-good` tag in the sync payload for Swiggy and Zomato. After this commit: --- - Now, products with GST != 5% correctly include the `packaged-good` tag in their respective provider tag list (`swiggy` or `zomato`). task-4954571 Forward-Port-Of: odoo/enterprise#90991 Forward-Port-Of: odoo/enterprise#90595
Appointments in some time zones were wrongly shown as unavailable when they overlapped the UTC date boundary before a next-day all-day calendar event. The fix checks all-day event timing using the user’s local time zone, so valid evening appointment slots remain bookable.
Original PR description
All-day calendar events were incorrectly causing unavailability for appointment slots scheduled on the previous evening, due to mismatches between local time and UTC. Previously, all-day events…
All-day calendar events were incorrectly causing unavailability for appointment slots scheduled on the previous evening, due to mismatches between local time and UTC. Previously, all-day events scheduled for Tuesday were stored with a start time of 00:00 UTC. In timezones like America/Chicago, this corresponds to 7:00 PM Monday. As a result, a valid appointment booked from 6:30 PM to 8:00 PM local time on Monday would partially fall into Tuesday in UTC (ending at 01:00 UTC), causing a false conflict with Tuesday’s all-day event. The `calendar_verify_availability` method now calls the newly added `_get_date_boundaries` which than computes naive datetime boundaries based on the user's local timezone by taking the end of the previous local day and the start of the next local day. This change resolves those edge cases where evening slots crossing the UTC boundary were falsely marked as unavailable due to timezone misalignment. opw-4614544 Forward-Port-Of: odoo/enterprise#85654
Fixed an issue where partially processing a lot-tracked receipt in the Barcode app could incorrectly increase the receipt demand after returning to it. This keeps inventory operations accurate when users complete remaining quantities across multiple barcode sessions, including batch picking flows.
Original PR description
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back…
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back to the picking register the 9 remaining units - Exit the picking and comeback #### > The demand of the receipt has been updated from 10 to 19. ### Cause of the issue: Exiting the picking will launch a call of the `post_barcode_process` in order to keep track of the changes you made without changing the initial demand: https://github.com/odoo/enterprise/blob/c26c21cec14a234021bb13bbc2684334bc64b70b/stock_barcode/models/stock_move.py#L50-L53 THe first time you enter the picking you have a single move with a quantity of 10. The first time you exit, since you have set a qty_done of 1 (and hence have updated the quantity of the associated move to 1), the `split_uncompleted_moves` will then create a move for a quantity of 9 in order to keep 10 units assigned. The second time you enter the picking both moves are grouped in a single line since the product is tracked by lot, however, when you update the qty_done of that grouped line you will actually only update the quantity of the first move line and its related move. Since the `_truncate_overreserved_moves` was not designed to handle these grouped lines, it does not notice that the combined reservation overcomes the actual demand. opw-4731803 Forward-Port-Of: odoo/enterprise#90497 Forward-Port-Of: odoo/enterprise#89967
Barcode scans for warehouse locations now only match locations belonging to the active company. This prevents users in multi-company setups from being sent to the wrong internal location when companies share the same barcode.
Original PR description
Description of the issue/feature this PR addresses: When scanning a location by barcode, the system may return the wrong location if multiple companies have internal locations with the same barcode. This is because the search does not currently filter by company. Current behavior before PR: The system searches for a location using only the barcode and usage='internal', without restricting by company. If multiple companies use the same barcode for different locations, the first match (regardless of company) is returned. Desired behavior after PR is merged: The location search is now restricted to the active company. Forward-Port-Of: odoo/enterprise#89286
The Philippine BIR 2307 spreadsheet export now aligns with required reporting details by accounting for ZIP codes and using the proper tax description for payment nature. This helps businesses produce more accurate withholding tax certificates and reduces the risk of reporting mistakes.
Original PR description
The BIR 2307 XLS export was missing the `ZIP_code` and incorrectly showing the `nature` of payment from the invoice line instead of the tax description. In this commit: --- - updates the tests to include the `zip_code` column and fetch the correct `nature` from the tax description. - adjust name fields to reflect individual vs company partner logic. community-PR- odoo/odoo#214940 --- task-4880921 Forward-Port-Of: odoo/enterprise#91202 Forward-Port-Of: odoo/enterprise#91120
This fix prevents an error in manufacturing work orders when a user clears and then reselects a start date in time tracking. Users can now adjust time tracking entries without encountering a blocking traceback.
Original PR description
When the user removes the value of the start date and selects the value again in the start date, a traceback will appear Steps to reproduce the error: - Create one mo > Work orders > Add a line >…
When the user removes the value of the start date and
selects the value again in the start date,
a traceback will appear
Steps to reproduce the error:
- Create one mo > Work orders > Add a line > Click on Open work order button
- In Time Tracking > Add a line > Remove the start date >
Select the start date again > Apply
Traceback:
```
TypeError: '<' not supported between instances of 'bool' and 'datetime.datetime'
File "odoo/http.py", line 2373, in __call__
response = request._serve_db()
File "odoo/http.py", line 1903, in _serve_db
return self._transactioning(
File "odoo/http.py", line 1966, in _transactioning
return service_model.retrying(func, env=self.env)
File "odoo/service/model.py", line 134, in retrying
result = func()
File "odoo/http.py", line 1933, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "odoo/http.py", line 2177, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "odoo/addons/base/models/ir_http.py", line 223, in _dispatch
result = endpoint(**request.params)
File "odoo/http.py", line 754, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "addons/web/controllers/dataset.py", line 35, in call_kw
return call_kw(request.env[model], method, args, kwargs)
File "odoo/api.py", line 459, in call_kw
result = getattr(recs, name)(*args, **kwargs)
File "addons/web/models/models.py", line 1007, in onchange
record._apply_onchange_methods(field_name, result)
File "odoo/models.py", line 7028, in _apply_onchange_methods
res = method(self)
File "addons/mrp/models/mrp_workcenter.py", line 448, in _date_start_changed
self._loss_type_change()
File "addons/mrp/models/mrp_workcenter.py", line 473, in _loss_type_change
if self.workorder_id.duration > self.workorder_id.duration_expected:
File "odoo/fields.py", line 1208, in __get__
self.recompute(record)
File "odoo/fields.py", line 1423, in recompute
apply_except_missing(self.compute_value, recs)
File "odoo/fields.py", line 1396, in apply_except_missing
func(records)
File "odoo/fields.py", line 1445, in compute_value
records._compute_field_value(self)
File "odoo/models.py", line 5037, in _compute_field_value
fields.determine(field.compute, self)
File "odoo/fields.py", line 101, in determine
return needle(*args)
File "home/odoo/src/enterprise/saas-17.4/mrp_workorder_hr_account/models/mrp_workorder.py", line 62, in _compute_duration
super()._compute_duration()
File "home/odoo/src/enterprise/saas-17.4/mrp_workorder/models/mrp_workorder.py", line 762, in _compute_duration
wo.duration = wo.get_duration()
File "home/odoo/src/enterprise/saas-17.4/mrp_workorder/models/mrp_workorder.py", line 838, in get_duration
duration += self._intervals_duration([(t.date_start, t.date_end or now, t) for t in times])
File "home/odoo/src/enterprise/saas-17.4/mrp_workorder/models/mrp_workorder.py", line 826, in _intervals_duration
for date_start, date_stop, timer in Intervals(intervals):
File "addons/resource/models/utils.py", line 124, in __init__
for value, flag, recs in sorted(_boundaries(intervals, 'start', 'stop')):
File "addons/resource/models/utils.py", line 51, in _boundaries
if start < stop:
```
https://github.com/odoo/enterprise/blob/1f626176d28762683dc32ddbb351d994be894a71/mrp_workorder/models/mrp_workorder.py#L787 Here when "date_start" is empty,
It leads to the above traceback.
sentry-5679416830
Forward-Port-Of: odoo/enterprise#91259
Forward-Port-Of: odoo/enterprise#68014Starshipit shipping requests now include the second address line when it is provided. This helps ensure complete delivery addresses are sent to the carrier, reducing the risk of shipping errors or missing address details.
Original PR description
Current behaviour: --- When using Starshipit, street2 is not included in the payload sent to the API. Expected behaviour: --- Street and Street2 should be both included if street2 is set, separated by a space. Steps to reproduce: --- 1. Install delivery_starshipit 2. Create starshipit Shipping Method 3. Create an Australian partner 4. Make sure street2 is set 5. Make a new sale order 6. Set the Australian partner 7. Set a product and click on "Add shipping" 8. Set starshipit as the method to use 9. Confirm and validate the delivery 10. Only the first street is sent opw-4907475 Forward-Port-Of: odoo/enterprise#90775 Forward-Port-Of: odoo/enterprise#89725
Fixed an issue where a signing document created by a user who was later deleted could fail to open. This helps users continue accessing and processing affected signature requests without encountering an error screen.
Original PR description
## Issue: ## Before this commit, opening a sign request created by a deleted user would raise an Owl Error ## Cause: ## The `action.params` are used as a fallback in the signRequest setup But sometimes sometimes the `action.params`are undefined, causing access to `action.params.create_uid` to fail ## Fix: ## The document can be open with `create_uid` set to False So we just added a check for `action.params` to be set before accessing his properties If the create_uid isn't in the context or in the params, it will be set to False ## Steps to reproduce: - Create a user (to be deleted later) - Create a sign request with this user - Delete the user - Try to open the sign request - The error should be displayed opw-4786368 Forward-Port-Of: odoo/enterprise#88758
Users with access to a specific field service task can now start and stop timers even when the related project is private. This prevents access errors and ensures their timesheets are created correctly without needing broader project access.
Original PR description
Before this commit, when the project is private and the user can only access to some tasks inside that project, he can create timesheets but cannot stop timer in one of those tasks when…
Before this commit, when the project is private and the user can only access to some tasks inside that project, he can create timesheets but cannot stop timer in one of those tasks when `industry_fsm` module is installed. This commit makes sure the user can start/stop a timer on task for which he has access to even if the project is private and he does not have access to it. Steps to reproduce the issue: ---------------------------- 0. install industry_fsm module 1. Create a project A with "followers" as privacy visibility 2. Create a task A and assign it to a project user with lowest timesheet access right. 3. log in as that user 4. Start a timer on Task A 5. Stop the timer and confirm the wizard Expected Behavior: ----------------- The timesheet should be created without any issue Current Behavior: ---------------- An Access error is raised because the user has no access to the project. task-4680412 Forward-Port-Of: odoo/enterprise#91015 Forward-Port-Of: odoo/enterprise#84807
Kitchen ticket printing now works reliably when using IoT-connected printers, including cases where the system needs to fall back to websocket communication. The point of sale also loads the necessary IoT device information more consistently, preventing frontend errors when configured devices have not changed recently.
Original PR description
Due to a missing `iot_id` field when the `DeviceController` for kitchen printers is instantiated, the websocket fallback does not work. This results in kitchen tickets failing to print even when regular receipts are working correctly. The fix is to provide the full IoT device model to the `DeviceController` constructor, as is done elsewhere. To do so we now pass the `device_id` field for the preparation printer model from the backend. We also ensure IoT devices/boxes are loaded even with a 'limited' load. This is because of an issue where an IoT device is added to the PoS config, but because the device itself has not be written to recently, the PoS doesn't load it and you get a traceback in the frontend.
This fixes an issue where a payment line could get stuck if a Worldline payment terminal disconnected during payment processing. Cashiers can now remove that payment line and complete the sale with another payment method, reducing checkout disruption.
Original PR description
If the terminal disconnects for any reason while processing a payment, we need to be able to remove the payment line the pos, to allow paying using another method.
Fixes an error that could occur when printing a follow-up letter from a partner's action menu. Users can now generate follow-up letters for overdue invoices through this flow without encountering a traceback.
Original PR description
### Steps to reproduce: - Settings > Technical > Reporting > Reports - Search for "Print Follow-up Letter" - Click on "Add to the Print menu" - Create an overdue invoice for a partner - On the partner page, click the gear to show the actions - Then click "Print Follow-up Letter" - Traceback ### Cause: This [line](https://github.com/odoo/enterprise/blob/82375d181cd138b497e695e747b63c009c0538fc/account_followup/models/res_partner.py#L291) tries to read `options['followup_line']` but with this flow `followup_line` is not in the options. ### Solution: Use `get` and fallback on the followup line on the partner. opw-4864880 Forward-Port-Of: odoo/enterprise#88543
The Starshipit shipping cost banner now appears only for deliveries using a Starshipit delivery method. This avoids confusing users working with other carriers when shipping costs are not set.
Original PR description
A Strashipit banner was appearing on all deliveries, un-depending on the Delivery Method. Steps to reproduce: * Install 'delivery_starshipit' * Create a delivery with another Delivery Method selected, and a Carrier Price of 0. * The Starshipit banner "The Shipping Cost is being fetched in the background" appears Fix: Filter out 'invisible' condition on non-Starshipit delivery methods opw-4940717 Forward-Port-Of: odoo/enterprise#90994