Daily updates from Odoo
Monday, August 11, 2025
21 changes · 18.0
New functionality added to Odoo
This update adds support for an additional IVA tax rate in the Uruguay localization. It helps businesses using Odoo in Uruguay record and report transactions that fall under this other VAT rate more accurately.
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
Enhancements to existing features
Company branches in Saudi localization will no longer automatically reuse the parent company's e-invoicing API mode or private key. This helps each branch maintain its own compliant ZATCA setup and avoids incorrect sharing of sensitive configuration between related companies.
Original PR description
Description of the issue/feature this PR addresses: When a branch is created for a company it inherits the `l10n_sa_private_key` and `l10n_sa_api_mode` of the parent company, which is which is incorrect and non-compliant from both an Odoo workflow and ZATCA's perspective Current behavior before PR: When you try to create a branch, it automatically inherits the `l10n_sa_api_mode` and `l10n_sa_private_key` of the parent company. Desired behavior after PR is merged: When you try to create a branch, its `l10n_sa_api_mode` and `l10n_sa_private_key` will be independent from the parent company. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222159
Romanian localization now includes the new 11% and 21% VAT rates and related tax groups introduced by recent legislation. Existing tax group assignments were also aligned for more consistent reporting and tax configuration.
Original PR description
This PR adds new taxes and tax groups for 11% and 21% after new VAT law was introduced in Romania. It also fixes tax groups of some taxes and make it more consistent. TaskID:4979168 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221238
Updates Romanian SAF-T reporting data so newly introduced taxes are classified with the correct tax type and code. This helps businesses stay aligned with recent Romanian tax law changes and keeps SAF-T report outputs accurate.
Original PR description
New taxes were introduced in Romania as per the new tax Law. The PR https://github.com/odoo/odoo/pull/221238/files added new taxes in community. This PR updates the SAF-T Tax Type and Code for the newly added taxes. TaskID:4979168 Forward-Port-Of: odoo/enterprise#91512
Resolved issues and error corrections
Paid time off in the French localization now uses the employee's actual work schedule when calculating hours, instead of defaulting to the company's schedule. This prevents timesheets from underreporting leave hours when an employee works longer days than the company default, while keeping French leave day-count rules intact.
Original PR description
With the French fiscal localization: When an employee has a different working schedule than the company’s default one. If the employee’s daily working hours are greater than the company’s default…
With the French fiscal localization: When an employee has a different working schedule than the company’s default one. If the employee’s daily working hours are greater than the company’s default hours. The timesheet for paid time off only displays the company’s default hours instead of the employee’s actual hours. Steps to reproduce: ------------------- * Install l10n_fr_hr_holidays * Set the French fiscal localization * Working schedule of the company -> 7:30 per day * Working schedule of the employee -> 8 per day * Create a paid time-off with this employee * Check the Timesheet of this employee > Observation: Timesheet shows 7:30 instead of 8 Why the fix: ------------ We needed to ensure the hours are always calculated correctly (using the employee’s or company’s calendar when appropriate) while still forcing the correct day count (1 or 0.5) and extending it according to French law. ✅ Day count is forced (0.5 or 1) depending on the leave type. ✅ Hours are fetched from `super()._get_durations()` so the timesheet keeps accurate hours. This prevents timesheets from showing incorrect hours when the employee's work schedule differs from the company's work schedule. opw-4744516 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Portal users sharing Microsoft Office documents will now have the file type saved consistently with the corrected file name. This prevents Office files such as spreadsheets from being treated as zip files, allowing users to open and work with them as expected in Odoo.
Original PR description
Issue: Inconsistent mimetype vs filename for documents shared by portal users. 1. Share a ms office document logged in as a portal user. 2. filename is correct, but mimetype is `application/zip`. 3.…
Issue: Inconsistent mimetype vs filename for documents shared by portal users. 1. Share a ms office document logged in as a portal user. 2. filename is correct, but mimetype is `application/zip`. 3. User can't interact with the file to open the file in the Odoo spreadsheet because the mimetype is zip. <img width="387" height="192" alt="image" src="https://github.com/user-attachments/assets/be31f05f-e4e3-44d9-b12a-66f96feba950" /> <img width="274" height="67" alt="image" src="https://github.com/user-attachments/assets/93064e5c-c028-41ce-8e79-1b9c9447c018" /> With `fix_filename_extension()`, the following two commits fixed the issue of Odoo's `guess_mimetype` function incorrectly guessing extensions such as `.xlsx` as `.zip` extension. https://github.com/odoo/odoo/commit/8842b6b43e7c3d1cc67d7d399bb210e4009e23b2 https://github.com/odoo/odoo/commit/34d9375e2efb604f8e7036cb710f44b01f9ccaee However, the `_from_request_file()` still uses the incorrectly guessed mimetype to create an attachment, leading to inconsistent extension from the filename (.xlsx) vs attachment record's mimetype (.zip). This commit fixes the issue by using the mimetype from the filename's extension. This is safe if the following assumption is correct: At the point where the `from_request_file()` attempts to create the attachment record, the `filename` contains correct extension name, presumably fixed by the `fix_filename_extension()`. Commit message to be changed after with Julien's confirmation; opw-4753670 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes incorrect access information being shown for portal document conversations. Users accessing documents through shared portal links will now get accurate permissions, helping avoid misleading interface options.
Original PR description
Before this commit, the `_thread_to_store` method would always set the `hasReadAccess` property to true. This was fine because the only flow that would add the values to the store would already check the existance and access to the thread. However after change [1] the access values would be sent in more flows, one of which being portal chatter initialization. This causes the client to have incorrect access information to the thread (i.e. hasReadAccess would be true even when accessing portal document through token). This commit fixes the issue by sending the correct access values. [1] https://github.com/odoo/odoo/pull/220774
Purchase orders now choose the vendor pricing rule that matches the ordered quantity instead of simply picking the cheapest rule for the same vendor. This prevents incorrect low-volume purchases from being priced with bulk discounts meant for larger quantities.
Original PR description
Steps to reproduce the bug: - Create a storable product “P1” - Under the Purchase tab: - add two vendor pricelist entries: 1:/ - Vendor: Azure Interior - min_qty: 1 - Price: $5 2:/ - Vendor: Azure…
Steps to reproduce the bug:
- Create a storable product “P1”
- Under the Purchase tab:
- add two vendor pricelist entries:
1:/
- Vendor: Azure Interior
- min_qty: 1
- Price: $5
2:/
- Vendor: Azure Interior
- min_qty: 100
- Price: $2
- Create a purchase order:
- vendor: Azure Interior
- Try to add the product P1
**Problem:**
When adding a product to a purchase order, if multiple supplier info
lines exist for the same vendor, the one with the lowest price will be
selected, instead of the one matching the smallest applicable quantity
(min_qty).
This regression was introduced by the following commit, which
tried to fix an unrelated bug with supplier info date matching:
https://github.com/odoo/odoo/commit/7eabfcff402993f32f5c835e18e07c91782a7b33#diff-5684edced9bdfc98021a85de4c6cdf691ea7add74e56ab50334a1d7db9ef4224L470
As part of that fix, the logic was changed to use the _select_seller
method, which by default sorts supplier info lines by price_discounted
and returns the first one — regardless of whether the min_qty is met.
Previously, the logic correctly selected the supplier line based
on min_qty when multiple lines existed for the same vendor.
**_Note:_** This bug is no longer present as of version 18.1, because
the date-related issue was fixed differently in the following commit:
https://github.com/odoo/odoo/commit/19c65c4884a3746b44b6272694662eb32a6bf32f
That later fix preserved the original behavior of respecting min_qty.
**Solution:**
Explicitly pass ordered_by='min_qty' when calling _select_seller.
This ensures that supplier info lines are prioritized based on the
lowest applicable min_qty, not the lowest price, when the vendor is the
same.
opw-4942819
Forward-Port-Of: odoo/odoo#221764This fixes a Point of Sale issue where orders from a closed session could fail to invoice when cash rounding was involved. Businesses can now create invoices for these POS orders reliably, avoiding blocked accounting workflows caused by unbalanced entries.
Original PR description
Currently it's not always possible to invoice an order from another sessio nthat is already closed when there is cash rounding. Steps to reproduce: ------------------- * Enable cash rounding for cash methods only, 5cents half-up * Open pos session * Add a produc with price 174.99 to order * Add a customer * Go to pay * Select pm cash and enter 100 * Select pm bank and enter 75 * Change 0.01 * Validate * Close session * Open session * Try invoicing the precedent order > Observation: Not possible to invoice, move is not balanced Back porting as it is exaclty the same issue: https://github.com/odoo/odoo/commit/626c3fd1bff85cc6cb222bdba80c14dd761dafd3 opw-[4829919](https://www.odoo.com/web#id=4829919&view_type=form&model=project.task) Forward-Port-Of: odoo/odoo#220096
This fix ensures operations covered by articles 22, 23 and 24 are included in section 60 of Spain's Model 303 VAT report. It helps Spanish companies produce more accurate VAT declarations and reduces the risk of incorrect tax reporting.
Original PR description
Operations included in articles 22, 23 and 24 should be included in section 60 of the model 303 report: source: https://declarando.es/modelo-303/casillas-59-60-y-61? opw-4954870 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#221686
Sales order lines now refresh the unit price when a quantity change qualifies for a different pricelist rule. This prevents customers from being quoted outdated prices and helps sales teams apply configured pricing consistently.
Original PR description
**Steps to reproduce**: 1. Install the `sale` module. 2. Enable `Pricelists` under `Settings > Sales > Pricing > Pricelists`. 3. Create two pricelists: - Pricelist A with two fixed-price rules: -…
**Steps to reproduce**:
1. Install the `sale` module.
2. Enable `Pricelists` under `Settings > Sales > Pricing > Pricelists`.
3. Create two pricelists:
- Pricelist A with two fixed-price rules:
- `0.75` for quantity ≥ 0
- `0.50` for quantity ≥ 1000
- Pricelist B with a `-10%` discount applied to Pricelist A.
4. Create a Sales Order using Pricelist B.
5. Add a product to the order line.
6. Increase the quantity to 1000.
**Observed behavior**:
- The unit price does not update according to the pricelist rule for quantity ≥ 1000.
- If you switch the pricelist to another and then back again, the `Update prices` button appears and correctly updates the price.
**Root cause**:
- The price is not recomputed when the quantity changes because the `price_unit` is not updated because it does not match the `technical_price_unit`.
- Since PR [#21392](https://github.com/odoo/odoo/pull/213912), `price_unit` is rounded (2 decimals), but `technical_price_unit` is not. This causes a mismatch in comparison logic due to rounding differences.
**Solution**:
- Replace direct float comparison with `currency_id.compare_amounts()` to ensure proper comparison with rounding precision.
opw-4944644Review and rating popups now stay aligned with the related discussion thread across portal pages, course pages, and chat components. This fixes inconsistent review editing or display behavior, giving users a more reliable feedback experience.
Original PR description
portal, portal_rating, rating, website_slides task-4743757
Leave requests for employees with flexible working hours now correctly count as zero days when they fall on a public holiday. This prevents employees' leave balances from being reduced for days that should not require time off.
Original PR description
**Steps to reproduce:** 1) Create a flexible working schedule. 2) Assign this schedule to an employee. 3) Create a public holiday. 4) Create a leave request for the flexible employee on the public…
**Steps to reproduce:** 1) Create a flexible working schedule. 2) Assign this schedule to an employee. 3) Create a public holiday. 4) Create a leave request for the flexible employee on the public holiday. 5) Notice that the duration of the leave is 1 instead of 0. **Issue:** Due to recent changes in the [commit](https://github.com/odoo/odoo/commit/a826f65c2d95b796f919023d560ec9f0801090d8#diff-38469def2f870bb866f971f57797dd7c21b6a95d52a8eae72f832f0eea2434f9R427-R433) , When a single-day flexible leave is taken, the duration is always set to the real duration. However, we do not check if the leave falls on a public holiday, which results in the leave being set to 1 day, even on holidays. https://github.com/odoo/odoo/blob/8f24da78f60529ea0b1840e48de30e15d17ddb77/addons/hr_holidays/models/hr_leave.py#L427-L433 **For example:** If Christmas is marked as a public holiday and an employee with a flexible schedule requests a one-day leave on Christmas, the leave is recorded with a duration of 1 day. **Fix:** Check for a public holiday on leave date; if yes, set leave duration to 0. opw-4963122
Internal users without administrator rights can now send Spanish FacturaE invoices without encountering an access error. This removes an unnecessary permission blocker in the invoicing workflow while keeping certificate handling consistent with existing behavior.
Original PR description
Non-admin users were hitting an “Access Error” when sending an invoice in facturae format, the onchange reads `company.l10n_es_edi_facturae_certificate_ids`, which reads certificate.certificate…
Non-admin users were hitting an “Access Error” when sending an invoice in facturae format, the onchange reads `company.l10n_es_edi_facturae_certificate_ids`, which reads certificate.certificate records , resulting in an “Access Error” popup. This changes Wrap the certificate lookup in company.sudo(). It's handled the same in https://github.com/odoo/odoo/blob/18.0/addons/l10n_es_edi_facturae/models/account_move.py#L140 https://github.com/odoo/odoo/blob/18.0/addons/l10n_es_edi_facturae/models/account_move.py#L770 install l10n_es_edi_facturae Go to Contacts and create an new contact with Spain as country in the same page (creating contact page) click on Accounting scroll down and set eInvoice format as facturaE Go to Accountant and create an invoice with that client pay the invoice log out and log in with a user with no administration (e.g. Marc demo) try to send the create invoice OPW:4989007 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents the background invoice sending process from failing when an invoice is changed back to draft or canceled before it is sent. It ensures only valid posted invoices are processed and clears outdated sending information, improving reliability for accounting workflows.
Original PR description
This commit makes the asynchronous invoice sending process more robust. Previously, the `_cron_account_move_send` method would fail if it encountered an invoice that was not in a 'posted' state. This could happen if a user changed the state of an invoice back to 'draft' or 'canceled' after it was selected for sending but before the cron job ran. To fix this, we added an extra condition to the search domain, so that only posted invoices are accounted for. We also added an explicit reset of `sending_data` in the draft button method, so that setting a posted invoiced back to draft does not retain (outdated) sending data. Steps to reproduce: 1. Select posted invoices and send. 2. Before cron runs, set one invoice to 'draft'. 3. Manually run the cron job `_cron_account_move_send`. 4. Observe the traceback. OPW-4985528 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an accounting issue where manually adjusting and then restoring a tax amount on Portuguese vendor bills could incorrectly reduce the untaxed total by one cent. This helps keep invoice totals accurate and prevents small but confusing accounting discrepancies.
Original PR description
**Issue** When using the Portuguese localization (`l10n_pt`), manually changing and resetting a tax amount on a vendor bill can incorrectly alter the base (untaxed) amount. **Steps to Reproduce** 1.…
**Issue** When using the Portuguese localization (`l10n_pt`), manually changing and resetting a tax amount on a vendor bill can incorrectly alter the base (untaxed) amount. **Steps to Reproduce** 1. Install Accounting and Portuguese localization (`l10n_pt`) 2. Create a vendor bill with a line: price = 123, tax = 23% 3. Manually change the computed tax amount from 28.29 to 28.30 4. Change it back to 28.29 5. Save the invoice 6. Observe that the untaxed amount becomes 122.99 instead of 123.00 **Root Cause** In the Portuguese localization, the tax delta logic compares `raw_total_amount` instead of `raw_base_amount` to detect rounding differences. However, the `raw_total_amount` field is not recomputed when the tax amount is manually edited. As a result, the system detects a false positive delta (0.01) and incorrectly subtracts it from the base amount to force reconciliation of totals. **Fix** Extend the delta correction loop to also update `raw_total_amount` and `raw_total_amount_currency`, not just `tax_amount` and `tax_amount_currency`. This ensures all totals are correctly adjusted after a manual tax change, and prevents the base amount from being unintentionally altered. Opw-4943540 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Calendar events can now sync to Google even when a multi-company user handles an event organized by someone with access to only one company. The sync now uses the organizer’s valid company context, preventing access errors and reducing disruption for teams using multiple companies.
Original PR description
**Description** When syncing a calendar event to Google, the system impersonates the event organizer in a multi-company context, this causes an access error if the current context includes companies…
**Description** When syncing a calendar event to Google, the system impersonates the event organizer in a multi-company context, this causes an access error if the current context includes companies the organizer does not have access to. --- **Steps to Reproduce** - Create Company B and organizer user (Company A access only) - Set current user to have access to both companies - Login as the organizer user - Go to Calendar app - Create a new event with Google sync enabled - Login as multi-company user - Select both companies in company switcher - Navigate to the event created by organizer - Trigger Google Calendar sync (accept/decline event) --- **Before** ` Access to unauthorized or invalid companies` **Root cause:** - The sync switches to the organizer's identity but keeps the original multi-company context - This creates a mismatch where the organizer doesn't have access to all companies in the context - Results in access violation when trying to sync **After:** - Properly scope the company context to match the organizer's company when switching user identity - This ensures the sync operation runs within the correct company boundaries opw-4911040 Forward-Port-Of: odoo/odoo#221193
Project profitability figures now use the accounting line balance, avoiding incorrect currency conversions based on today's or manually changed exchange rates. This makes project dashboards align more reliably with analytic accounting reports, especially for foreign-currency vendor bills or historical transactions.
Original PR description
Issue description: The profitability items for projects were not matching the numbers from analytic accounting reports due to discrepancies in currency rate calculations. This issue was traced to two…
Issue description: The profitability items for projects were not matching the numbers from analytic accounting reports due to discrepancies in currency rate calculations. This issue was traced to two main causes: 1. Profitability items were using the currency rate of today, even for old move lines. ```rates = self.env['res.currency'].browse(list(currency_ids))._get_rates(self.company_id, date.today())``` While this was deemed acceptable for performance reasons in #113146, it caused mismatches with analytic accounting reports. 2. Some move lines use a changed currency rate that differs from the rate stored in the currency table for the same date (due to manual change in the currency rate), leading to further mismatches. To resolve this: - The `balance` is now used instead of `price_subtotal` for calculations. This ensures accurate amounts without relying on conversion rates when the project currency matches the company currency. Steps to Reproduce: 1. Create a project with an associated analytic account. 2. Enable any foreign currency and add different rates for it for today and yesterday. 3. Create a new vendor bill with: - Date = yesterday - Currency = the new foreign currency - Analytic distribution set to the created project's analytic account. 4. Check the project dashboard profitability. You will see the numbers are incorrect because it uses the currency rate of today. opw - 4881380 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221168 Forward-Port-Of: odoo/odoo#217337
Swiss payroll declarations now show which employee details are missing before users send or print them. This helps payroll teams identify and correct issues more easily, reducing confusion and failed or incomplete declarations.
Original PR description
It is currently complicated for non trained users to figure out what is missing before sending or printing a declaration. In this PR we extend the warning mechanism to declarations to visualize what information is missing on what employees. Forward-Port-Of: odoo/enterprise#86195
When portal users contribute Excel files that are converted into Odoo spreadsheets, their access is now safely adjusted to view-only. This prevents conversion errors caused by unsupported edit access for portal users, making the document workflow smoother for internal teams.
Original PR description
Let's say a Document Folder is shared with a portal user with 'edit' access. The portal user shares a .xlsx file to the folder, and an internal user later try to convert the file to odoo spreadsheet.…
Let's say a Document Folder is shared with a portal user with 'edit' access. The portal user shares a .xlsx file to the folder, and an internal user later try to convert the file to odoo spreadsheet. During the conversion, the portal user has 'edit' role on the folder, which is copied to the documents.access records of the converted sheet. Since Odoo prevents Spreadsheets from being shared in edit mode to portal users, _check_spreadsheet() raises a Validation Error. <img width="702" height="527" alt="image" src="https://github.com/user-attachments/assets/efee9a8b-161f-4def-9597-cf03ac4c54e3" /> To improve the user experience, this commit overrides `copy_data` of `documents.access` model to assign `view` access to portal users for an odoo spreadsheet. Maybe we can extract the if-conditions, and make it an API to reduce repeated code, as the same logic is being used in `_check_spreadsheet()` on the same file. However, looping through the copied vals_list only when handler is spreadsheet might have more value in terms of performance. opw-4753670
Internal users can now see the Documents app button, making it easier to access shared documents directly. This also clarifies that users do not need the full Documents User role to access documents shared with all internal users.
Original PR description
The app is accessible to all internal users via smart buttons and their portal already, showing the button is helpful in two ways: 1/ Easier access to the app, duh. 2/ Makes it explicit that you don't need to be a "Documents User" to have access to documents shared with all **internal users**, even those that are not documents user (that didn't have the app button available). In 18.0 so that new installations have it. Task-4889053