Daily updates from Odoo
Tuesday, September 23, 2025
13 changes · 17.0
Enhancements to existing features
Italian electronic invoice imports now keep the document type from the original XML and no longer rely on separate type variants that duplicated the same document code. This makes invoice and bill handling more consistent when the same FatturaPA document type can apply to either sales or purchases.
Original PR description
In the FatturaPA XML, the Document Type (Tipo Documento) doesn't indicate the direction of the journal entry. A `TD01` can be an `in_invoice` or `out_invoice` depending on whether the company is set to be the seller or the buyer. That's what we consider when importing invoices from the EDI. - saved the `l10n_it_document_type` from the imported bills' XML - removed the filter in the view - removed the `l10n_it_document_type` duplicates that just differed by `l10n_it_document_type.type` - updated the invoices to point to the original `l10n_it_document_type` if there were duplicates We will have to remove the field in `master` See odoo/upgrade#8484
Resolved issues and error corrections
This fix prevents manufacturing work order planning from failing when no start date is available. If the start date is missing, the system now uses today’s date as a fallback, helping production scheduling continue without interruption.
Original PR description
The issue occurs when the system tries to convert different types of date or date objects into proper python datetime.datetime object but 'date_start' is False in vals at [1]. It might be write when…
The issue occurs when the system tries to convert different types of date or date objects into proper python datetime.datetime object but 'date_start' is False in vals at [1]. It might be write when `_plan_workorders` is executed and mrp workorder has not 'leave_id' [2]. The issue occurs when the system attempts to convert various date or date-related objects into a valid Python datetime.datetime object. However, at [1], 'date_start' in 'vals' is False [1]. This may be write when the '_plan_workorders' method is executed and the mrp workorder does not have a 'leave_id' [2]. Link [1]: https://github.com/odoo/odoo/blob/a848c3854c94b5c2b752edddbcf49337acf9d6ea/addons/mrp/models/mrp_production.py#L875 Link [2]: https://github.com/odoo/odoo/blob/a848c3854c94b5c2b752edddbcf49337acf9d6ea/addons/mrp/models/mrp_production.py#L1533-L1536 To resolve this, provide a default date as today if start date is not available Sentry-6255515427 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Website domain settings are now checked before they are saved, preventing invalid entries with spaces or overly long domain parts. This avoids errors when visitors or search engines access site files such as robots.txt and gives users a clear message to correct the domain.
Original PR description
The system did not previously validate the `website_domain` field, which could result in domains with invalid formats (e.g., containing spaces or exceeding the maximum acceptable length). The error is generated when the user sets the long domain and tries to access `/robot.txt`. **Steps to Produce:-** 1. Go to **Website's setting > set too long Domain > Save**. 2. Remove all after the first `/` from the URL and add **robots.txt**. **Error:-** `QWebException: Error while render the template` `UnicodeError: label too long` **Solution:-** - Added a constraint on the website_domain field. - The domain must: - Not contain any spaces. - Not exceed 71 characters. - Labels of domain should not exceed 63 characters. - A ValidationError is raised with a descriptive message if any of these conditions are violated. **sentry-6613845697** I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Kenyan eTIMS submissions no longer fail when a vendor bill includes an invoice line without tax. This prevents an error during submission and lets users continue processing valid vendor bills even when tax details are absent.
Original PR description
Currently, an error occurs when clicking the "Send to eTIMS" button on vendor bills. Steps to Reproduce: - Install the l10n_ke_edi_oscu module without demo data. - Create a new company with Kenya as the country and switch to it. - Go to Vendors > Bills, create a new bill, and add an invoice line without tax. - Confirm it, then click Send to eTIMS. StopIteration This error occurs because when the user removed the tax from the invoice line and clicked 'Send to eTIMS', the tax details got empty at [1]. As a result, no tax line is found using next(), which raises a StopIteration error. [1] https://github.com/odoo/enterprise/blob/e9cd1fa8c11d5d9a3dce7a8027a9ac9e19f44190/l10n_ke_edi_oscu/models/account_move.py#L234 This commit ensures that if there are no tax details present in the invoice line, the calculation of line_values is skipped for that case. sentry-6641334969
Swiss payroll now guides users to enter employee names in the expected first-name-then-last-name format. This also fixes the way legal first and last names are derived, helping SwissDEC payroll reports use the correct personal details.
Original PR description
* Add placeholder text to employee name field with Swiss cultural examples: "e.g. Roger Federer, Jean-Luc Godard, Johannna Spyri, ..." * Fix _compute_l10n_ch_legal_name method to correctly assign first_name and last_name from employee name (was previously reversed) * Update all SwissDEC test data to use correct "FirstName LastName" format instead of "LastName FirstName" to match the corrected computation logic task-5102851
CSV imports with missing columns or incorrect separators now show a clear validation error instead of failing unexpectedly. This helps users identify and fix formatting problems in their files, especially for large imports that may skip preview checks.
Original PR description
This error occurs when importing a CSV file containing rows with missing columns or incorrect separators. Large files may bypass preview checks, leading to failures during the actual import. **Steps to replicate:** * Settings>User & Companies>Users >Gear icon>Import Records * Import the [csv file](https://drive.google.com/file/d/1rkYjuiS_8ZO94lBwt_DvPbuRDr36xW1N/view?usp=sharing). * Set role field > title > Import `IndexError: list index out of range` **Solution:** * Catch `IndexError` during row processing and raise a `ImportValidationError` to handle rows with missing or misaligned columns. **Sentry-5588088802**
The website shop price range filter now uses corrected close-match search terms when calculating available price limits. This prevents shoppers from losing the ability to filter by price after a near-miss search, improving product discovery and checkout flow.
Original PR description
Versions
--------
- 17.0+
Steps
-----
1. Navigate to the website shop page.
2. Search for a term that is close to an existing one, but not exact ("dask" instead of "desk" for example)
Issue
-----
The price range filter will stop functioning
Cause
-----
The domain used to get the minimum and maximum prices for the price range filter used the original search term regardless of whether the actual search results are from a fuzzy search term or not
Solution
--------
When there is a fuzzy search term use it to get the minimum and maximum prices for the price range filter instead of the original search term
opw-5020545This update corrects rounding behavior when Mexican companies register payments in pesos for invoices issued in a foreign currency. It helps prevent valid payment e-invoices from being rejected due to small currency conversion differences.
Original PR description
Steps to reproduce:
- With an MX Company setup
- Set USD rate to:
- 0.049216958195 for day 1
- 0.053418803419 for day 2
- Create an invoice in USD as follows:
- line 1: price_unit 91, quantity 64, tax 16%
- Confirm and send CFDI
- Register full payment in MXN
- Send Payment CFDI
Issue: Payment validation will fail with error
Code : CRP20268
Message : El campo BaseP que corresponde a Traslado, no es igual a la suma de los importes de las bases registrados en los documentos relacionados donde el impuesto del documento relacionado sea igual al campo ImpuestoP de este elemento y la TasaOCuotaDR del documento relacionado sea igual al campo TasaOCuotaP de este elemento.
This occurs because the precision set in
e642e4d6d35c79d02c799d12451f3e2d92ab96e9 is too high and can lead to failed verification due to rounding issues
opw-4750981WhatsApp chats now update to the correct contact when a phone number is moved from one contact record to another. This prevents new messages from showing the old contact name, reducing confusion for teams managing customer conversations.
Original PR description
Issue: When we have a Whatsapp contact that we have already used and for some reason we decide to move this contact phone number to a different contact, then when receiving or sending messsages again to this contact, we will still see the old contact name for the new messages. Steps to reproduce: Notice: You will need to follow the steps needed to set up a Whatsapp account and connect it to the db. 1. Create a new contact with the phone number linked to your whatsapp. 2. Start a conversation with this contact through whatsapp. 3. Move now the phone number, to a different contact. 4. Send messages again from the whatsapp to our db. Solution: We could fix this by checking inside the _get_whatsapp_channel if our channel whatsapp partner still has a phone number linked to it, if it doesn't, then we should try to retrieve the new contact that has our phone number linked to, and set it as our whatsapp partner. opw-3812366
Grouped views now exclude archived records, such as inactive contact tags, from group headings while still allowing empty values. This keeps reports and list groupings focused on active business data and avoids confusion from outdated categories.
Original PR description
**Steps to reproduce:** - Create a new tag - Add it to a contact - Archieve the new tag - Groupo the contacts by tags - The archived tag is still present as a column of the group_by results **Issue:** When a user performs a group by on a view with `webReadGroup`, if a record of the field used for grouping is archived, it still appears in the search results. This is caused by the field used not being filtered by its `active` status. **Fix:** Add a custom domain filter for the field of the group_by which can be overwritten. The filter allow unset value for the field and restrict the rest to records with active = true. opw-5032604 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Calendar events created with booking lines now correctly retain the resources selected by users. This prevents appointments from appearing without their assigned resources after saving, improving scheduling accuracy.
Original PR description
**Steps to reproduce:** 1. Create or use a calendar event with a resource. 2. Now go to the calendar view of that event. 3. Click to make an appointment and go to More Options. 4. Add a booking line…
**Steps to reproduce:** 1. Create or use a calendar event with a resource. 2. Now go to the calendar view of that event. 3. Click to make an appointment and go to More Options. 4. Add a booking line and select a resource. 5. Save the event. **Issue:** When creating a calendar event with booking lines, the `resource_ids` field is not correctly populated. This is due to the fact that the compute method relying on `booking_line_ids` does not work at creation time, as the One2many lines have not yet been created in the database when the compute runs. As a result, events created this way appear without any linked resources, even though the user selected them through the booking lines. **Fix:** To avoid relying on the computed field during record creation, we explicitly extract `appointment_resource_id` values from the inline booking lines in the incoming `vals_list` and assign them directly to `resource_ids`. This ensures that resource information is preserved at creation time, without relying on deferred compute logic that cannot access the booking lines yet. opw-4565161
The company switcher now correctly displays nested company structures when a user can access a parent and a deeper child company, even if an intermediate company is not accessible. This prevents users from missing companies they are allowed to use and keeps the hierarchy clear by showing unavailable intermediate companies as disabled.
Original PR description
### Issue: Given a specific configuration, the `SwitchCompanyMenu` will not display all the companies a user can access. Suppose we have a company hierarchy with the following: `Company 1 > Company 2…
### Issue: Given a specific configuration, the `SwitchCompanyMenu` will not display all the companies a user can access. Suppose we have a company hierarchy with the following: `Company 1 > Company 2 > Company 3` (where 2 is a branch of 1, and 3 is a branch of 2). If a user has access to C1 and C3, but not C2, the menu selector will only display C1, rather than a hierarchy of all 3 companies with C2 disabled. This menu has been improved between versions, but the logic behind how we determine which companies to display remains consistent. We loop over each root company from `companyService.allowedCompaniesWithAncestors`, add it, and then add its children. Depending on whether the child company is accessible, it will be disabled (but still displayed) in the hierarchy list. `companyService` pulls its company information from the `session['user_companies']` dict that is created from `session_info`. For each of the `allowed_companies`, we build the `child_ids` from the intersection of each `user.company_id.child_ids` and `user.company_ids`. So we only add the child if it itself is an allowed company, which C2 would not be. C1 is now considered a root company with no children in our loop, so C2 is skipped. C2 isn't a root company either, so it will never be seen, and therefore neither will C3. ### Solution: A similar case was addressed in #138942, where given the same company hierarchy as above, the user instead has access to C2 and C3, but not C1. This PR adjusted how we build the `child_ids` for `disallowed_ancestor_companies` (C1 in this case), properly setting the children for us to loop through. We can use this same logic for the `child_ids` of `allowed_companies`, ensuring we can properly loop through the disallowed children of allowed companies. Additionally, we need to adapt the `CompanySelector` component, which previously grabbed all children even if they were disallowed. opw-4880477
This fix prevents external report values from being changed once they fall within locked accounting periods. It helps preserve finalized tax report data, such as after a closing entry is posted, reducing the risk of inconsistent or unauthorized post-closing changes.
Original PR description
[FIX] account_reports: external value check lock date This commit add the check that protects external values from being edited out of the lock dates. For example when the closing entry from the tax report is posted, the user is not supposed to modify any external values anymore. This commit is kind of a backport for what has been done in 18.0, see odoo/enterprise#92949 Also it has to be NOT fw-port as it's a 17.0 version ONLY task-5012442