Wednesday, August 13, 2025
14 changes · 18.0
Enhancements to existing features
This update adds Mexican localization support for additional 16% withholding tax scenarios with split distributions, along with the related accounts and fiscal positions. It also improves tax precision so 10.67% taxes can be calculated and displayed more accurately for compliant accounting.
Original PR description
Add few 16% taxes with special distribution (1/3 - 2/3 and 1/4 - 3/4). Also add few accounts and a new fiscal position for each new tax. Also adjust the rounding precision of 10.67% taxes. Linked:https://github.com/odoo/enterprise/pull/83582 task-4571928
Mexican localization now includes additional 16% withholding tax setups with specific split distributions, plus matching accounts and fiscal positions. The update also improves rounding precision for 10.67% taxes, helping businesses calculate and report these tax scenarios more accurately.
Original PR description
Add few 16% taxes with special distribution (1/3 - 2/3 and 1/4 - 3/4). Also add few accounts and a new fiscal position for each new tax. Also adjust the rounding precision of 10.67% taxes. Linked:https://github.com/odoo/odoo/pull/206406 task-4571928
Resolved issues and error corrections
This fix ensures Spanish POS orders follow the correct Veri*Factu workflow: eligible orders can be sent after session closing, already registered orders no longer show an unusable send option, and cancellations are blocked in favor of refunds. This helps businesses avoid unsupported compliance actions and reduces confusion for staff handling Spanish electronic reporting.
Original PR description
- The "Send Veri*Factu" button is currently also visible for registered orders (but we can not send documents for such orders anyway; we do not support subsanacion) - We do not allow generating Veri\*Factu documents for posted orders. That makes it impossible to (Veri\*Factu) send orders after the session is closed. - We should not allow to Veri*Factu cancel orders. They would still be included in the closing move. The user should create refund instead. task-None Forward-Port-Of: odoo/odoo#222668
Point of Sale now applies the same tax treatment in the user interface as in the backend when an order includes a negative line. This prevents mismatched totals and helps avoid accounting entries becoming unbalanced.
Original PR description
Before this commit, when an order contained a negative line, the backend treated it as a refund line while the POS UI did not. This mismatch caused inconsistent tax calculations between the UI and the backend, which could result in unbalanced journal entries. With this commit, the tax calculation logic is aligned between the UI and the backend, ensuring consistency and preventing unbalanced moves. opw-4972314 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Partner autocomplete now uses standard industry codes instead of internal database IDs when receiving Dun & Bradstreet data. This prevents errors when a customer has customized, removed, or recreated industry records in their Odoo database, improving reliability during company data enrichment.
Original PR description
Ticket #4992568 highlighted a weird way of sending the industry from IAP to the Odoo client. Before this commit, we were sending the IAP psql id of the industry to the client. There, it would be use as is. It works because these industries haven't been changed in years and they're created in the same order. However the ticket highlighted the fact that a user can edit/delete/create its own industries, therefore some ids that exist on IAP might not exist on the client's Odoo instance. This resulted in a traceback on the client's side. With this commit, we now send the industry code (the ISIC: International Standard Industrial Classification) instead to the client. There it can correctly be mapped if it exists on the client's DB (e.g. not deleted) opw-4992568 https://github.com/odoo/iap-apps/pull/1152 Forward-Port-Of: odoo/odoo#222486
This fixes sales reporting for Point of Sale orders when the same product appears on multiple order lines and is shipped later. Delivered quantities are now split correctly across the lines, preventing inflated totals such as reporting 16 delivered instead of 8.
Original PR description
If you made a sale with multiple lines having the same product, the qty_delivered was not correctly computed on the different lines. Steps to reproduce: ------------------- * Activate the ship later…
If you made a sale with multiple lines having the same product, the qty_delivered was not correctly computed on the different lines. Steps to reproduce: ------------------- * Activate the ship later option in the PoS settings * Open PoS * Add any product with a quantity of 5 * Apply a discount of 20% to the line * Click on the same product so that they are added as a second line * Change the quantity of the second line to 3 * Validate the order and use the ship later option * Validate the picking * Go to the sale report and check the qty_delivered for the product > Observation: The qty_delivered is doubled, 16 instead of 8. Why the fix: ------------ The qty_delivered was computed by summing the quantities of all moves for the product, but it did not take into account that the same product could be present in multiple lines of the same order. We now make sure to dispatch the delivered quantity correctly across the different lines of the order, ensuring that the qty_delivered is accurate. opw-4826487
Uninstalling the Marketing Card module could leave behind database leftovers and block clean reinstallations. This fix skips unnecessary cleanup during module removal so uninstall and reinstall operations complete reliably.
Original PR description
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for…
Because it overrides the unlink of `IrModel` odoo/odoo#214315 breaks a ton of model uninstall/reinstall (basically all its dependencies, direct or transitive): when `marketing_card` is marked for uninstallation, all its fields get removed first (because that's how `_module_data_uninstall` does things), so all the non-magic columns are dropped. Then, when trying to `unlink` the `ir.model` records the `unlink` call fails with some sort of "column does not exist" error (on `active` or `res_model`), the unlink fails, which leads the tables to not be removed, leaving a ton of garbage in the database. This in turns means trying to reinstall the module also fails, as many tables will have a few records left for one reason or another before they are dropped, so new columns which are `required` without a `default` fail to set up their constraint, which logs both errors and warnings on reinstall. None of this is necessary, if `marketing_card` is being uninstalled we can just ignore the entire issue as the table should be dropped eventually, even if it worked it would be a waste of time. https://runbot.odoo.com/odoo/error/230837
Saudi e-invoice QR codes now use the amount due on the specific invoice instead of the full sales order total. This prevents ZATCA warnings on regular invoices after down payments and helps invoices be accepted cleanly.
Original PR description
#### Step to reproduce: - In a company in Saudi Arabia - Create a sale order to a customer (B2C) - Create an invoice as a downpayment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) - Create an invoice as a regular payment and confirm it - Process the ZATCA invoice if needed (blue banner at the top) #### Current behavior: - ZATCA return a 200 code for the downpayment invoice. - ZATCA return a 202 code with a Warning for the regular payment invoice. The warning states that the invoice was accepted however it needs the Tag 4 of the QR code to be Amount due payment (BT-115) #### Expected behavior - ZATCA return a 200 code on both invoices. opw-4848578 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219464
Users can now restore an earlier task description from history, make further edits, and save without seeing an incorrect history-related error. This prevents disruption when using task version history and helps keep project work updates reliable.
Original PR description
Problem: When applying a specific version from history in `task.description`, then updating and saving it, an error appears stating the content was saved from a different history model. Cause: When inserting versioned content, the required `data-last-history-steps` attribute is not included. Solution: Ensure the latest `data-last-history-steps` is added when restoring a version. Steps to reproduce: - Open Project > any task - Change the description - Save - Open version history and apply any version - Update the description - Save - Error appears opw-4829553 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prevents an error when a user linked to one company views an e-commerce website or products belonging to another company. It ensures the website can read the company currency needed for product display, improving reliability for multi-company online stores.
Original PR description
A multi-company issue can occur when a user from another company tries to access products belonging to a different company. Steps to reproduce: 1. Create a e-commerce website without a pricelist on company A 2. Create a user assigned with only access to company B 3. Connect with this user and try to access the products on the website of company A An error will be raised because the user does not have access to company A. opw-4983506 Forward-Port-Of: odoo/odoo#222457
The German EC Sales List CSV export now includes the required version information expected by the Elster portal. This prevents valid reports from being rejected during upload and helps businesses submit their EU sales declarations without manual correction.
Original PR description
When uploading the EC Sales List csv to Elster.de portal, users will see the file rejected with the following error (EN translated) """ Your CSV file was created for an older version of the CSV interface. Please refer to the version table in the import help for the latest version of the interface and any changes. If the version information is correct, please check the encoding of your CSV file. The permitted encoding is UTF-8. """ This occurs because the csv is missing the version strings identifying the versions of data format References: https://www.elster.de/eportal/helpGlobal?themaGlobal=zmdo_import_eop https://www.datev-community.de/t5/Betriebliches-Rechnungswesen/Import-CSV-Daten-nacvh-Elster-f%C3%BCr-ZM/td-p/480079 opw-4850314
Fixes an error that could occur when users enabled the Account Types filter and expanded an account in the General Ledger report. This improves reliability for finance teams using filtered ledger views, especially for payable and receivable accounts.
Original PR description
Steps to reproduce:
- Open general ledger configuration
- Under Options tab, set filter Account Types as "Payable and receivable"
- Open General Ledger report
- Unfold an account
Traceback will raise
```
File "[...]/odoo/tools/query.py", line 101, in add_join
assert self._joins[alias] == (sql_kind, table, condition)
AssertionError
```
Because of the account types filter we already add a "LEFT JOIN" between account_move_line and account_account
Then, trying to add a "JOIN" between the same tables, the system find a different type of JOIN and fails the assert
opw-4742411The recurring invoice job now checks a larger set of subscriptions so eligible subscriptions are less likely to be skipped when some records are filtered out. This helps businesses avoid missed subscription invoices during scheduled billing runs while keeping performance safeguards in place.
Original PR description
**Steps to reproduce** With the default batch size of 30: - create 1 subscription not requiring payment and confirm it - create 31 subscriptions requiring payment and confirm them - launch the…
**Steps to reproduce** With the default batch size of 30: - create 1 subscription not requiring payment and confirm it - create 31 subscriptions requiring payment and confirm them - launch the "Generate recurring invoices" cron - the first subscription is not invoiced **Cause** Issue since commit https://github.com/odoo/enterprise/commit/9bad2716c3903ff89dad5f1d4bc0a2fb39c76293 Since the search with the `_recurring_invoice_domain` only returns the first batch_size + 1 records, and a subsequent filtering by `_get_subscriptions_to_invoice` is applied, `len(all_subscriptions) > batch_size` doesn't guarantee that there aren't more subscriptions to invoice not returned by search. **Solution** Increase the limit's size so that `need_cron_trigger` is True in the case where some records are filtered by `get_subscriptions_to_invoice`. In the case where a lot of subscriptions are filtered and the issue still persists, increasing the `batch_size` to process all subscriptions is necessary. The limit is not removed for performance reasons. opw-4766637
The portal now shows total hours based only on validated timesheets when that invoicing policy is selected. This keeps the displayed total consistent with the visible timesheet lines and avoids overstating billable or tracked work for customers.
Original PR description
### Steps to reproduce: - Set timesheets inovicing policy to 'Validated Timesheets Only' - From the portal go to any task that has some validated timesheet and some other not - Notice that the lines…
### Steps to reproduce: - Set timesheets inovicing policy to 'Validated Timesheets Only' - From the portal go to any task that has some validated timesheet and some other not - Notice that the lines shown is the validated ones only but the Hours spent includes the non-validated ones too ### Current behavior before PR: The total hours spent for timesheets in portal view when setting the invoicing policy to 'Validate Timesheets Only' is calculated wrongly as it takes the non validated ones into account. This is happening as when passing the values to the view we pass 'task_sudo' variable which will have the SUPERUSER as the env.user https://github.com/odoo/odoo/blob/saas-17.2/addons/project/controllers/portal.py#L569 so it won't pass the condition if the user is portal or not https://github.com/odoo/enterprise/blob/saas-17.2/sale_timesheet_enterprise/models/project_task.py#L33:L35 and it will calculate all the timesheet without taking validation into condisderation. ### Desired behavior after PR is merged: As we are using those computed fields only in portal views so we don't have to check if the user is portal user as even if an internal user is showing the same view for testing he should be able to see the same data as the portal user. opw-4193842