Daily updates from Odoo
Monday, July 14, 2025
16 changes · 18.0
Resolved issues and error corrections
Portal users can now upload Excel, Word, and similar office documents without Odoo mistakenly treating them as ZIP files. This preserves the expected file names and formats in shared Documents workspaces, reducing confusion and failed document handling.
Original PR description
Issue: .xlsx files shared by portal users being converted into .zip files. https://drive.google.com/file/d/1MgHOrCW4QOVWmlYES-qWUQwEBH2M5gjk/view https://www.odoo.com/odoo/action-4043/4607156…
Issue: .xlsx files shared by portal users being converted into .zip files.
https://drive.google.com/file/d/1MgHOrCW4QOVWmlYES-qWUQwEBH2M5gjk/view
https://www.odoo.com/odoo/action-4043/4607156
https://www.odoo.com/odoo/my-support-tasks/4753670
How to reproduce:
1. Share a Documents workspace with a portal user.
2. Ensure the portal user has "edit" rights on the workspace. (so that he/she can share documents.)
3. Log in to the portal as the portal user.
4. Navigate to the shared workspace.
5. Upload an Excel (.xlsx) or Word (.docx) file.
6. Issue: The files are now .zip files.
Background:
In commit [9a1dec8](https://github.com/odoo/odoo/commit/9a1dec8eea5eae3a3e801dd2210fefa8a05ae485), the _from_request_file() method was introduced to guess a file's mimetype by analyzing only its first 1024 bytes.
https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/odoo/addons/base/models/ir_attachment.py#L769-L771
The guessing process ultimately calls zipfile.ZipFile(), which requires the entire file content to correctly parse OOXML formats.
https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/odoo/tools/mimetypes.py#L28-L42
Because we only provided the initial chunk, zipfile could not detect the file as `.zip` file, raising Error.
```
2025-06-10 14:49:54,049 61227 WARNING odoo_18_empty2 odoo.tools.mimetypes.guess_mimetype: Sub-checker '_check_open_container_format' of type 'application/zip' failed
Traceback (most recent call last):
File "/Users/sujuodoo/odoo18/odoo/odoo/tools/mimetypes.py", line 159, in _odoo_guess_mimetype
guess = discriminant(bin_data)
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/sujuodoo/odoo18/odoo/odoo/tools/mimetypes.py", line 59, in _check_open_container_format
with io.BytesIO(data) as f, zipfile.ZipFile(f) as z:
^^^^^^^^^^^^^^^^^^
File "/Users/sujuodoo/.pyenv/versions/3.11.6/lib/python3.11/zipfile.py", line 1302, in __init__
self._RealGetContents()
File "/Users/sujuodoo/.pyenv/versions/3.11.6/lib/python3.11/zipfile.py", line 1369, in _RealGetContents
raise BadZipFile("File is not a zip file")
zipfile.BadZipFile: File is not a zip file
```
(Handled by Line 158 -167 below, where `discriminant()` = `_check_ooxml()`)
Consequently, it fell back to the generic application/zip mimetype. ( Line 168-170 below)
https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/odoo/tools/mimetypes.py#L154-L170
https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/odoo/tools/mimetypes.py#L122-L144
We already load the entire file in memory to `self.create()`, so I'm assuming it is fine to do so earlier in the code and pass it to the `guess_mimetype` -> `_odoo_guess_mimetype`, but at the same time I guess this might me a technical limitation.
https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/odoo/addons/base/models/ir_attachment.py#L778-L784
I'm curious how you guys think about this.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix ensures express checkout customer details are updated correctly when the website is used in languages where order references appear in a different position in generated partner names. It helps prevent checkout and delivery information from staying outdated for translated storefronts such as Spanish.
Original PR description
[FIX] website_sale: handle translated express checkout partners Versions -------- - 17.0+ Steps ----- 1. Change website language to Spanish 2. add a deliverable order to cart; 3. go via express checkout. Issue ----- The express checkout partner doesn't get updated as expected. Cause ----- Before this commit, it checks whether the express checkout partner's name ends with the order reference, as is the case in English. In Spanish however, the order reference gets used in the middle of the name. As a consequence, the `_create_or_edit_partner` method does not get called. Solution -------- Check whether the order reference is part of the partner name. opw-4894059 Forward-Port-Of: odoo/odoo#217528
Factur-X electronic invoices now use deferred start and end dates when they are available, instead of defaulting to the invoice and due dates. This helps businesses send more accurate compliant invoice data for services delivered over a specific period.
Original PR description
### Issue: The FacturX XML has a field `BillingSpecifiedPeriod`, it should depend on `deferred_start/end_date` if they are there. Currently, it only outputs the invoice date as start date and the due…
### Issue: The FacturX XML has a field `BillingSpecifiedPeriod`, it should depend on `deferred_start/end_date` if they are there. Currently, it only outputs the invoice date as start date and the due date as end date. ### Steps to reproduce: - Install "l10n_de" and switch to a German company - Go to a contact, in the page Accounting > Electronic Invoicing change the format to "Factur-X (CII)" - Create an invoice for this contact - Add a start date and end date on the line of this invoice (`deferred_start/end_date`) - Confirm and send to Factur-X - In the generated XML the dates used are the invoice date and the due date ### Cause: As the `deferred_start/end_date` fields are defined in enterprise and the XML generation is in community, this [commit](https://github.com/odoo/odoo/commit/f0c5d5b46444a289bf55ad5846623d48ac3a3b71) set dates defined in community instead of the deferred ones. ### Solution: Mimicking [the way it's done for UBL20](https://github.com/odoo/odoo/blob/638268a81ed5a292a02d7fc353c4954159de54e1/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py#L846) we check if `deferred_start/end_date` are defined (i.e. account_accountant is installed). If it's the case, we use the min/max of the `deferred_start/end_date` as start/end date of the `BillingSpecifiedPeriod` in the XML. To include as much info as we can this commit also adds the `deferred_start_date` and `deferred_end_date` on lines. opw-4874370 Forward-Port-Of: odoo/odoo#215595
Fixes and usability improvements for Greece myDATA e-invoicing make invoice submission more reliable and reduce manual rework. The update corrects VAT formatting, error handling, PDF generation, invoice type defaults, settings placement, and default classification values to help users create and send compliant invoices more smoothly.
Original PR description
First major fixes and improvements for Greece EDI. task-4781479
This update prevents users from creating duplicate Italian electronic invoicing document type codes. It avoids invoice confirmation failures caused by duplicated document type records, making the invoicing process more reliable.
Original PR description
**Issue** : The computation of `l10n_it_document_type` fails when multiple `l10n_it.document.type` records share the same code. This can happen if a user duplicates an existing Document Type or…
**Issue** : The computation of `l10n_it_document_type` fails when multiple `l10n_it.document.type` records share the same code. This can happen if a user duplicates an existing Document Type or creates a new one with the same code, causing `get()` on the grouped recordset to return multiple results.
**Traceback :**
```python
File "/home/odoo/odoo/codebase/odoo/17.0/odoo/fields.py", line 3252, in convert_to_cache
raise ValueError("Wrong value for %s: %r" % (self, value))
ValueError: Wrong value for account.move.l10n_it_document_type: l10n_it.document.type(1, 23)
```
**Steps to Reproduce:**
1. Install the `l10n_it_edi_ndd` module.
2. Go to Customer Invoices and create a new invoice.
3. Set a Document Type, then confirm the invoice.
4. Open that Document Type and duplicate it.
5. Create another invoice without setting a Document Type, then confirm it.
observation: you will receive a traceback for wrong value error
**Solution :** This fix adds a check to ensure that the `code` field remains unique across all `l10n_it.document.type` records.
opw - 4902513
related upgrade pr : https://github.com/odoo/upgrade/pull/8032
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#217155This update fixes editor issues that could create malformed lists when pasted content included list items without a surrounding list, and could prevent users from removing bold or italic formatting across multi-paragraph selections. This helps keep website and HTML editor content structured correctly and makes formatting controls behave reliably.
Original PR description
**Current behavior before PR:** **Issue 1:** - Paste a content with multiple `<li>` elements without `ol/ul` tag, each `<li>` having a paragraph element inside. - Try to create a list from these…
**Current behavior before PR:** **Issue 1:** - Paste a content with multiple `<li>` elements without `ol/ul` tag, each `<li>` having a paragraph element inside. - Try to create a list from these elements. - List is created with wrong element structure. The problem occurs because when pasting multiple `<li>` elements without an `<ol>/<ul>` tag, `sanitizeNode` replaces existing `<li>` elements with new `<p>` elements. Since each `<li>` already contains a `<p>`, this results in paragraphs being nested inside other paragraphs. As a result, creating the list from these paragraphs leads to an incorrect structure. **Issue 2:** If there are multiple paragraph selected along with newline character nodes `(\n)`, it is not possible to remove bold or italic format from selected content using toolbar. The issue happens because `isSelectionFormat` method fails to give correct value if traversed nodes contains one or more newline `(\n)` characters. **Desired behavior after PR is merged:** **Issue 1:** Now, if an `<li>` contains a `<p>`, the `<li>` is unwrapped instead of creating a new paragraph, resulting in a correct element structure when creating a list. **Issue 2:** Now, `\n` nodes are filtered from traversed nodes so that format can be removed from selected content. task-4752385 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208127
This fix prevents users from changing another company's currency when that company already has journal items. It ensures existing accounting activity is detected correctly across companies, helping protect financial data consistency.
Original PR description
To_reproduce: ============== 1- switch company. 2- update any other company currency that has journal items. 3- company currency changed. Problem: ========= - When switching companies, users could update the other company's currency even when journal items existed for that company. Solution: Solution: ========= - Added .sudo() to the account.move.line search to bypass access rights and properly detect existing journal items in that company. opw-4920206 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217988 Forward-Port-Of: odoo/odoo#217929
This fixes planning calculations for flexible employees so their work intervals cover the intended flexible period instead of behaving like standard employee schedules. This helps ensure planning availability and related scheduling decisions reflect flexible work arrangements accurately.
Original PR description
Bug: - flexible employee work intervals are similar to work intervals for normal employees. Source: - condition to return an Interval covering all the period is _is_fully_flexible Fix: - condition changed to _is_flexible
Self-service and kiosk order numbers now include an S or K prefix, making it easier for staff and customers to identify where each order came from. The order number is shown consistently across tickets, receipts, preparation screens, and preparation receipts, with receipt header display limited to restaurant setups where it applies.
Original PR description
- Add a prefix `S` or `K` (respectively for Self and Kiosk orders) to the `tracking_number` for the Self/kiosk orders. - Display the `tracking_number` in the receipt header only if `pos_restaurant` is installed. - This prefix will be displayed on the ticket screen, on the receipt, on the preparation display and on the preparation receipt for coherence and to facilitate tracking of orders. task-id: 4922308 enterprise PR: https://github.com/odoo/enterprise/pull/90042 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change reverts a recent analytic accounting update that caused errors when validating transactions using mandatory project analytics on expense accounts. It restores the previous behavior so affected accounting workflows can be completed reliably.
Original PR description
This reverts commit 8194c6e2bfedc9437964090b1a498c3e8cff225c. Steps to reproduce: - Modify analytic plan "project": default applicability: optional domain: miscellaneous financial account prefix: 6 applicability: mandatory - create a transaction - on the transaction > manual operation change account to expense put an analytic for "Projet" - validate opw-4936028 opw-4933629 opw-4935236 opw-4933456 opw-4933652 opw-4935789 opw-4938570 opw-4938388 opw-4935709 opw-4940233 opw-4938849
This fixes an error that could occur when changing reordering quantities for manufactured products during replenishment updates. Users can now adjust those rules without the process failing, improving reliability for inventory and manufacturing planning.
Original PR description
**Steps to reproduce:** - Install MRP module - Create a new product tracked by quantity and set its route to manufacture - Create a new BoM and set the Manuf. Lead Time to 2 days - Create a new…
**Steps to reproduce:**
- Install MRP module
- Create a new product tracked by quantity and set its route to manufacture
- Create a new BoM and set the Manuf. Lead Time to 2 days
- Create a new reordering rule, set the minimum quantity to 2 and click on order
- Navigate to the newly created manufacturing order and set the scheduled date to the next day
- Try increasing the minimum quantity on the reordering rule
- `KeyError` is triggered
**Issue:**
When computing `unwanted_replenish` field, the `_quantity_in_progress` function builds a dictionary (`res`) created using the IDs of current 'stock.warehouse.orderpoint' records as keys.
During `onchange()` process the keys can be set as temporary IDs (`NewID` class). But, when evaluating domains, `orderpoint.id` is returned as the real ID (`orderpoint._origin.id`), which make the index lookup fails when checking value of existing model:
```
self.id => NewId origin=6
res => {<NewId origin=6> : 0.0}
orderpoint.id => 6
res[orderpoint.id] => KeyError
```
This mismatch occurs due to the implicit conversion when using `NewId` inside domain filters with `.ids`. In which case they return the elements which matched the `_origin` id (for previous existing records). Domains will return the matching records with real IDs, but the dictionary still expects `NewId` as key.
**Fix:**
Ensure safe lookup by explicitly checking whether the dictionary has either the real ID or the `NewId` wrapper.
opw-4729116
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prWhen purchased goods fail a quality check and are moved to a failure location, Odoo now updates the linked stock flow so the related sales delivery can continue correctly. This prevents sales orders from staying stuck waiting for availability after a failed inspection.
Original PR description
Steps to reproduce the bug:
- Unarchive the MTO route
- Create a product P1:
- Type: Storable
- Route: MTO + Buy
- Supplier: Vendor A
- Create a quality point:
- Product: P1
- Control per: Quantity
- Failure location: WH/input/order Processing
- Create a sales order for 1 unit of P1
- Confirm the SO → A purchase order is created for Vendor A with 1 unit of P1
- Confirm the PO
- Go to the related PO picking
- Fail the quality check
Problem:
picking related to the SO remains in the "Waiting Availability" state and the stock move is not switched to the Make to stock procure method
opw-4874199
Forward-Port-Of: odoo/odoo#216337This fixes an issue where bank reconciliation could conflict with automatic analytic accounting updates. The change helps prevent processing loops and keeps journal entry analytics consistent during reconciliation.
Original PR description
Since a recent fix[^1], the analytic distribution on journal entries is updated with any update made on analytic items. In order to avoid loops and do things in the right order, a context key was added. However, the reconciliation widget was also manipulating analytic items, so it needed to use the context key as well. opw-4936028 opw-4933629 opw-4935236 opw-4933456 opw-4933652 opw-4935789 opw-4938570 opw-4938388 opw-4935709 opw-4940233 opw-4938849 [^1]: https://github.com/odoo/odoo/commit/8194c6e2bfedc9437964090b1a498c3e8cff225c
When a purchased item fails a quality check and is moved to a failure location, the related customer delivery no longer stays stuck waiting for the original item. The system now switches the affected stock move to use available stock, helping orders continue correctly after failed inspections.
Original PR description
Steps to reproduce the bug:
- Unarchive the MTO route
- Create a product P1:
- Type: Storable
- Route: MTO + Buy
- Supplier: Vendor A
- Create a quality point:
- Product: P1
- Control per: Quantity
- Failure location: WH/input/order Processing
- Create a sales order for 1 unit of P1
- Confirm the SO → A purchase order is created for Vendor A with 1 unit of P1
- Confirm the PO
- Go to the related PO picking
- Fail the quality check
Problem:
picking related to the SO remains in the "Waiting Availability" state and the stock move is not switched to the Make to stock procure method
opw-4874199
Forward-Port-Of: odoo/enterprise#88791Odoo now includes depreciation amounts imported during a migration when showing cumulative depreciation and depreciation schedules. This prevents migrated assets from appearing under-depreciated and gives finance teams more accurate reports without creating duplicate journal entries.
Original PR description
Working:- - When migrating from any other accounting software to Odoo,in `Depreciated Amount(already_depreciated_amount_import)` field we put asset's depreciated amount till then(before migration).…
Working:- - When migrating from any other accounting software to Odoo,in `Depreciated Amount(already_depreciated_amount_import)` field we put asset's depreciated amount till then(before migration). This depreciation is recorded in each account when starting in Odoo(the original balances) and in Odoo creating Journal Entries are skipped for this imported depreciated amount. Example:- - Consider Asset with Original Value: \$10,000.00, Acquisition Date: 01/01/2020, Method: Straight Line, Duration: 10 Years, Computation: No Prorata. - Now according to our computation this asset will depreciate \$1000.00 for the years 2020 to 2029 each, and Journal Entries would be created on 31st December each year. - Now someone migrating from other software to Odoo in the year 2025 will put Depreciated Amount: \$5,000.00 . - Now Odoo will create Journal Entries for only years 2025 to 2029 and skip creating Journal Entries for the years 2020 to 2024 as these entries are created in previous accounting package and are recorded in original balances while migrating. Before this commit:- - In Depreciation Board, Cumulative Depreciation starts from \$1,000.00 for the year 2025 and goes till \$5,000.00 for the year 2029, ignoring imported depreciated amount. - Depreciation Schedule report displays constant \$5,000.00 as depreciated value for the years 2020 to 2024. After this commit:- - In Depreciation Board, imported depreciated amount is added in Cumulative Depreciation, so it starts from \$6,000.00 for the year 2025 and goes till \$10,000.00 for the year 2029. - In Depreciation Schedule Report, `_simulate_imported_depreciation` method will modify report values to simulated imported depreciation amount and skipped Journal Entries. task-4864528 Forward-Port-Of: odoo/enterprise#90012 Forward-Port-Of: odoo/enterprise#88127
Appointment bookings now reuse an existing contact when the same email address is used again, instead of creating a duplicate. This keeps customer records cleaner and reduces manual cleanup for teams managing appointments.
Original PR description
**Description** Booking an appointment on the website creates a new contact. If the same user books again, a duplicate contact is created instead of reusing the existing one. This is a regression from v17 where fallback logic prevented duplication. --- **Steps to Reproduce** 1. Book an appointment with a name, email, and phone. 2. Book a second appointment using the same data. 3. A new duplicate contact is created. --- **Before** * Existing contacts are not reused, causing duplicates. **After** * Existing contacts are reused if a matching email is found. --- This fix restores the fallback email search logic from v17 to avoid creating duplicates. **opw-4614897**