Monday, July 28, 2025
19 changes · saas-18.3
Enhancements to existing features
Italian e-invoicing registration now also sends a company’s VAT number as a backup identifier. This helps incoming vendor bills match the correct registered user when only the VAT number is available, reducing failed invoice processing.
Original PR description
This improvement addresses an issue in the Italian e-invoicing (l10n_it_edi) and IAP registration logic where incoming vendor bills with only a VAT number failed to match the correct registered EDI user. Changes introduced: - Added `edi_identification_secondary` (e.g. VAT number) to support fallback user matching. - Updated the `/create_user` endpoint to accept and store the secondary identifier. - Modified `create_user` logic to send both primary and secondary IDs from Odoo. - Prepared the base for matching incoming invoices against both identifiers. See also: odoo/iap-apps#1056 Task [link](https://www.odoo.com/odoo/project/967/tasks/4619718) task-4619718 Forward-Port-Of: odoo/odoo#219654 Forward-Port-Of: odoo/odoo#207753
Customers using self-ordering no longer see an extra payment confirmation screen after a successful transaction. This streamlines the checkout flow by taking them directly to the next step, reducing friction and wait time.
Original PR description
Before: = - A payment confirmation screen used to appear after a successful transaction. After: = - The flow now skips the payment confirmation screen and moves directly to the next Screen. Task: 4836123 Forward-Port-Of: odoo/odoo#213481
Spanish invoice sending now includes a dedicated Factura-e option directly in the Send & Print flow. This makes it easier for users to choose when to generate Factura-e files and helps keep customer invoicing settings consistent.
Original PR description
Currently, `Factura-e` generation is controlled only by an partner E-invoice format setting, making it difficult for users to enable or disable when sending invoices. This PR adds a dedicated Factura-e checkbox on the `Send & Print` wizard for partners in Spain if the `l10n_es_edi_facturae` module is installed. The checkbox defaults to the partner’s current `E-invoice format` but can be toggled by the user. When enabled, it triggers Factura-e file generation and updates the partner’s E-invoice format to ensure consistency. This approach simplifies the user flow and reduces configuration errors. > Task-4831835 Forward-Port-Of: odoo/odoo#214295
Businesses using the Türkiye reports can now export the General Ledger in the CSV format required for e-Ledger submissions. The file is automatically packaged as a ZIP archive, helping meet Türkiye Revenue Administration delivery requirements for selected reporting periods.
Original PR description
This PR implements the necessary functionality for Türkiye’s e-Ledger reporting, as mandated by Türkiye law (Law No: 15570). Taxpayers that switched to e-Invoice/e-Archive are also required to submit their General Ledger (GL) in the e-Ledger format. Summary of the change This update enhances the existing Türkiye General Ledger report in the `l10n_tr_reports` module with the following features: - Adds the ability for users to generate the General Ledger as a CSV file, formatted according to the Türkiye e-Ledger requirements. - Allows export for any selected period, including relevant and filtered fields. - The generated CSV file is automatically compressed into a ZIP archive to comply with the GIB (Türkiye Revenue Administration) guidelines for file delivery. Task-4270136 Forward-Port-Of: odoo/enterprise#90997 Forward-Port-Of: odoo/enterprise#86592
Resolved issues and error corrections
Corrects an issue where invoicing a closed point-of-sale order could fail when cash rounding was enabled only for cash payments and the customer used a mix of bank and cash payment. This helps businesses avoid blocked invoices and accounting imbalance errors in affected POS sessions.
Original PR description
Before this commit, an imbalance entry error occurred when invoicing a posted order under specific conditions. This issue arose when cash rounding was enabled only for the cash payment method, but the order was paid using both bank and cash. For example, if an order had a total of 12.91, and was partially paid with a bank transfer of 15.59, resulting in a cash return of -2.70, the session could be closed. However, attempting to invoice this order after closing the session would fail due to the imbalance. opw-4912399 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218430
Fixed an issue where customers who already had loyalty points could still claim a reward after the program's maximum usage limit had been reached in the current Point of Sale session. This helps ensure promotional limits are applied consistently and prevents unintended extra reward redemptions.
Original PR description
When an existing partner with points tries to claim a reward from a loyalty program that has reached its max usage in the current session, he was still able to claim the reward. Steps to reproduce: ------------------- * Create a loyalty program with max usage set to 1 * Create a partner and assign points to him * Open PoS and select any partner and make an order * Claim the reward from the loyalty program * Select the partner that already has points * Make an order and try to claim the reward again > Observation: The reward can be claimed, even though the max usage is already reached. Why the fix: ------------ When updating programs, we were not removing the couponPointChanges for programs that are not applicable anymore. We now make sure to delete them when the program is not applicable anymore. opw-4805704 Forward-Port-Of: odoo/odoo#220460 Forward-Port-Of: odoo/odoo#218425
Paid orders created through QR-code self-ordering now appear correctly in the POS ticket list. Staff will see the proper paid status and refund action, reducing confusion when handling already-paid customer orders.
Original PR description
**Steps:** - Configure POS with self-ordering via QR code and online payment. - Open a session and place a paid order through self-ordering. - In the POS UI, open the TicketScreen and apply the "Paid Orders" filter. **Issues:** - The paid order does not show the "Paid" tag. - The "Load Order" button appears instead of the "Refund" button. **Cause:** - The paid order retains an outdated uiState, with `uiState.locked` incorrectly set to false. **Fix:** - Use `finalized` instead of `uiState.locked` to determine order state on TicketScreen. - Remove the unused `locked` property from `uiState` in posOrder. Task: 4745869 Related: odoo/enterprise#86684 Forward-Port-Of: odoo/odoo#220193 Forward-Port-Of: odoo/odoo#207406
This update prepares Odoo for newer platform versions, including Python 3.13 and Debian Trixie, by adjusting dependencies and internal compatibility checks. It helps keep deployments reliable on upcoming operating system environments while also aligning tests with changed Python and library behavior.
Original PR description
Forward-Port-Of: odoo/odoo#220147 Forward-Port-Of: odoo/odoo#219270
This fix makes Odoo more accurately decide when users are allowed to publish website pages and partner-related content. It prevents misleading publish options from appearing when the user does not have the right access, reducing confusion and failed publishing attempts.
Original PR description
*: website_crm_partner_assign, website_customer, website_membership, website_partner Commit [1] (alongside commits [2] and [3]) introduced a new context key `can_publish_unsudo_main_object` with the…
*: website_crm_partner_assign, website_customer, website_membership, website_partner Commit [1] (alongside commits [2] and [3]) introduced a new context key `can_publish_unsudo_main_object` with the goal of properly computing `can_publish` without sudo... but it missed using it properly. The related test was passing... because it was also not properly written. This commit fixes the issue by using the context key at the proper places. However, this limits the fix to pages and partners at the moment as the bug is not critical in stable versions. It however fixes a test while run in no-demo (which becomes the norm in later versions). With that in mind, this also changes the view (by *adding* things to be as stable as possible) to go around the use of the context key and make new databases properly compute `can_publish` for all records type. Old databases will keep the old behavior for some models, which leads to displaying the "Publish" button but not be able to use it (access right warning). [1]: https://github.com/odoo/odoo/commit/d47d824fc484e1592fc4af8d0d378d5a4a579550 [2]: https://github.com/odoo/odoo/commit/1a83b2508b9383e2b7df192f8641751f71f852da [3]: https://github.com/odoo/odoo/commit/436a167dedb2ed008bcb88e8a4eccafc8d20812c Related to runbot-161791 Forward-Port-Of: odoo/odoo#220292 Forward-Port-Of: odoo/odoo#219389
Vendor bills created before goods are received now calculate foreign-currency amounts using the full billed quantity, not just one unit. This also prevents small unwanted exchange differences when the related receipt is later validated, improving accounting accuracy for purchase workflows.
Original PR description
**Current behavior:** Creating a purchase order in a foreign currency and billing the product prior to reception will produce 2 issues: A) The bill line for the product will only make a conversion of…
**Current behavior:** Creating a purchase order in a foreign currency and billing the product prior to reception will produce 2 issues: A) The bill line for the product will only make a conversion of 1 single unit of the product with the defined currency exchange rate, making the amount on the line incorrect when qty > 1 B) When the receipt is finally validated, there will be an unwanted exchange difference on the journal items generated due to asymmetrical rounding for the bill AMLs and receipt valuation AMLs **Expected behavior:** Correct bill line currency amounts and symmetric rounding. **Steps to reproduce:** 1. Set the company currenct to IQD, make a product invoiced on ordered qty, for sake of example set cost to 500 IQD 2. Create a currency exchange record to USD with a company rate of `0.00756` 3. Create a PO for 13 of the product created in step 1, with a discount of 1% 4. Confirm the PO and create the bill -> post it * Issue A) look at invoice line, see only 1 unit in the converted currency amount is accounted for by the `balance` 5) Receive the product -> look at the journal items generated and see that there is a diff of 0.185 IQD **Cause of the issue:** A) commit: 90158f6 added a method to try and calculate an AML balance from its purchase line values, but mistakenly is using `qty_received` instead of `qty_to_invoice` which explains why this issue only presents for the bill-before-receipt flow B) commit: 9f046d5 is using `round=False` context for `AccountTax.compute_all()` when the expected key is `round_base` **Fix:** A) Replace `qty_received or 1` with `qty_to_invoice` * Also make the test added in 90158f6 more robust B) Add `round_base=False` alongside the `round` key (not removing as that existing one could have become expected in this context) opw-4689170 Forward-Port-Of: odoo/odoo#216898 Forward-Port-Of: odoo/odoo#205850
This fixes two editor issues that could disrupt content editing: pasted list items now keep the correct structure, and bold or italic formatting can be removed even when selected text includes line breaks. The change makes website and HTML editing more reliable for users working with copied content and multi-paragraph selections.
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#217361 Forward-Port-Of: odoo/odoo#208127
This fix prevents valid product combinations from being incorrectly blocked in Point of Sale after an attribute line is removed from a product. It helps ensure staff and customers can continue selling available variants without disruption in POS and self-order flows.
Original PR description
Before this commit, removing an attribute line from a product would inadvertently prevent the sale of any combination in the PoS interface. opw-4947529 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219251
Reordering rules now respect the replenishment unit of measure, so purchase orders and related warehouse transfers match how vendors actually sell products. This also improves quantity rounding for packaged goods and prevents manufacturing orders from being updated with quantities in the wrong unit.
Original PR description
**PROBLEM** 1. When setting up a product with vendor that sell the product in different packaging, when triggering the reorder, the PO use the stock UoM instead of the replenishement UoM. 2. Once the…
**PROBLEM** 1. When setting up a product with vendor that sell the product in different packaging, when triggering the reorder, the PO use the stock UoM instead of the replenishement UoM. 2. Once the first issue is fixed, we can notice the packaging quantity in the picking order is not exactly what it should be (rounding error of 0.01). 3. Once the first issue is fixed, there is a failing test concerning the manufacture procurement route. **STEP TO REPRODUCE** 1. activate the UoM and packaging option. 2. create a product with a vendor that sells it in a packaging. 3. create a reordering rule with the replenishement UoM being the packaging unit. 4. trigger the reordering, notice the PO doesn't use the right unit and the picking doesn't use the right packaging. (Same steps to reproduce, just revert my change on stock_move.py before) (To reproduce the 3rd issue, run the test in odoo/addons/sale_mrp/tests/test_sale_mrp_procurement.py) **CAUSE** The procurement for the reordering rule is always created with the stock UoM. The `_compute_packaging_uom_qty` method doesn't specify the rounding_method to use when converting from the product uom to the replenishment uom. By default, it uses the 'UP' method. The _run_manufacture method has a bug: when there is a new procurement for a product that has already a mo opened, it will try to update the mo quantity. To do so, it calculate a new quantity, by adding the previous quantity and the procurement quantity, but it assumes the quantity is in the product default uom which is not always the case (for example, when there is a replenishment UoM set on the reordering rule). **FIX** 1. If a remplenishement uom exists on the reordering rule, we create the replenishement with this unit instead of the stock one. 2. Use the 'HALF-UP' rounding method, to reduce the rounding error. 3. Converting the procurement quantity into the product default UoM before computing the new mo quantity. opw-4858992
When a salesperson changes the product on a quotation line after manually editing its price, Odoo now recalculates the price for the newly selected product. This prevents quotes from accidentally keeping the old product’s price, improving pricing accuracy for sales orders.
Original PR description
step to reproduce - Create a quotation, - Select a product - Update the price manually - change the product - The amount stays the same expectation: with change of product in SO, price should also recompute issue: currently,`_compute_price_unit` depends on `technical_price_unit` such that `price_unit` won't update if `price_unit` and `technical_price_unit` are not same. which is the case when price_unit was manually set, regardless of the product https://github.com/odoo/odoo/blob/12ef230df58122fbdac0b4c1b4781c535b8516ba/addons/sale/models/sale_order_line.py#L567-L570 we should reset to original price with change of product opw-4813069 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218192 Forward-Port-Of: odoo/odoo#213912
Fixes an error that could block users from sending multiple invoices at once when the invoice email template had custom recipients configured. This helps accounting teams send invoices in bulk reliably without manual workarounds.
Original PR description
Currently, an error occurs when sending invoices in bulk. Steps to Reproduce: - Install the `account` module. - Go to `Email Templates` and open `Invoice: Sending`. - In the `Email Configuration`,…
Currently, an error occurs when sending invoices in bulk. Steps to Reproduce: - Install the `account` module. - Go to `Email Templates` and open `Invoice: Sending`. - In the `Email Configuration`, uncheck `Default Recipients` and enter `demo@gmail.com` in the `cc` field. - Go to `Invoices`. - Select multiple invoices and click `Send`. `KeyError: <NewId origin=33>` This error occurs when sending invoices in bulk. As mentioned in commit https://github.com/odoo/odoo/commit/058d324855a6e2fe3df51386aa153d46419766bf, the issue was introduced in commit https://github.com/odoo/odoo/commit/39d1907d77ca9c88431e7e9dc9e8c938c79a2987, where the _compute_alerts method attempts to set an alert in the wizard. However,since this is a computed field, the wizard record has a NewId and calls the method with a transient record [1]. When trying to access record.id, it returns a NewId [2], and later, when this NewId is used as a res_id [3],it raises a KeyError. [1]-https://github.com/odoo/odoo/blob/aff5f006d5b1996ea3ecc67998067cd0e292cf2a/addons/account/wizard/account_move_send_batch_wizard.py#L63 [2]- https://github.com/odoo/odoo/blob/c70bca77d0447b005b3898e1861facc2828475fc/addons/mail/models/mail_thread.py#L2037 [3]- https://github.com/odoo/odoo/blob/c70bca77d0447b005b3898e1861facc2828475fc/addons/mail/models/mail_thread.py#L2084 This commit fixes the above issue by using move_ids._origin, ensuring that the method is always called with real records, and removes the changes from the previous commit https://github.com/odoo/odoo/commit/058d324855a6e2fe3df51386aa153d46419766bf. sentry-6562659542 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217730
Installing Accounting Reports or Accountant after Accounting now creates the VAT return journal when needed, even if the chart of accounts was already set up. This helps prevent missing VAT closing records and makes tax return setup more reliable for companies and branches.
Original PR description
Issue: The VAT return journal is not created when installing `account_reports` (or `accountant`) after `account`, when the CoA is already created. Solution: Create it in the post init hook. Note that…
Issue: The VAT return journal is not created when installing `account_reports` (or `accountant`) after `account`, when the CoA is already created. Solution: Create it in the post init hook. Note that we force the creation of the journal only when `accountant` is installed because it would make noise for invoicing only in most cases. It will still be created automatically when needed. Also, make the code a little bit more robust: * instead of mixing "default misc journal" and vat return journal logic, just use one logic * the function `_get_tax_closing_journal` could return multiple journals but was always used as if it could only contain one * the function `_get_tax_closing_journal` could not return any journal. Instead, we now create the journal or look for a value on the parent companies if any. * Manage `show_on_dashboard` in `create` also by using an inverse field. Even if in normal cases the journal will always be created after the company the thus set through `write`, it is not impossible to set it in `create` when creating company branches. Since it is always done when setting the journal on the company, there is no need to set the field in the post-init hook.
Fixes accounting reconciliation so models using a different currency calculate foreign currency amounts and balances correctly. It also prevents automatic reconciliation models from being created when users apply receivable or payable actions, reducing unintended accounting setup changes.
Original PR description
Before this commit when applying a reco model with a different currency, the amount currency and the balance were equals. task-4931177 Before this commit when applying the receivable or payable button, the automatic reco models would be created. We don't want that behavior task-4930730
Mobile self-ordering orders are now sent to the preparation display as soon as the customer proceeds to pay, instead of waiting until cashier payment. This helps staff start preparing mobile orders earlier and avoids delays or missed visibility in the kitchen workflow.
Original PR description
When doing a self order from a mobile device, the order was not sent to the preparation display until it was paid at the cashier. Steps to reproduce: ------------------- * Setup a PoS with self-ordering mode set to 'mobile'. * Setup a preparation display to show orders from this PoS. * Place an order from a mobile device. * Click on "Pay" > Observation: The order does not appear on the preparation display. Why the fix: ------------ Instead of just sending the order from the kiosk, we also need to send it from the mobile device. opw-4819732 Forward-Port-Of: odoo/enterprise#90169
Online synchronization fields no longer disappear when provider data is not supplied by OdooFin. This keeps bank connection details accessible and corrects a related search filter, requiring a module update.
Original PR description
The fields on the online synchronization were invisible if no provider_data wass put on the synchro. But now, this info is not given anymore from Odoofin. So, we should not hide these fields based on provider_data. Also fixed a search domain. It will need an update of the module. Forward-Port-Of: odoo/enterprise#91027 Forward-Port-Of: odoo/enterprise#90785