Thursday, September 4, 2025
15 changes · saas-18.3
Enhancements to existing features
Odoo eCommerce can again sync product feeds with Google Merchant Center, helping merchants improve product visibility and keep listings updated. The feed now excludes shipping details to avoid slow processing and carrier rate limits, with product limits and caching added for better reliability at scale.
Original PR description
In [^1], a new feature was introduced to allow users to synchronize their eCommerce with Google Merchant Center and increase their product visibility, keep stock status updated, and improve product listings. However, the initial implementation attempted to include shipping information in the feed, which required computing rates for every product, carrier, and country. This quickly became infeasible due to performance constraints and third-party carrier rate limits, forcing us to disable the feature [^2]. This commit reintroduces the GMC feed without shipping details, making it lightweight and reliable. To ensure scalability, we also (i) enforce a limit of 5000 products per feed, and (ii) introduce a caching mechanism to avoid recomputing expensive product data (e.g., prices) for subsequent requests. task-5049357 [^1]: https://github.com/odoo/odoo/pull/186976 [^2]: https://github.com/odoo/odoo/pull/224649
Adds support for required official company information codes when sending Turkish e-invoices through Nilvera. Invoices are now blocked if mandatory codes are missing or empty, helping businesses avoid non-compliant submissions while ensuring the codes appear in both PDF and XML outputs.
Original PR description
Description of the issue/feature this PR addresses: Nilvera requires official codes on company contacts for submission to be compliant. Current behavior before PR: Invoices may be sent to Nilvera…
Description of the issue/feature this PR addresses: Nilvera requires official codes on company contacts for submission to be compliant. Current behavior before PR: Invoices may be sent to Nilvera without the required codes, resulting in non-compliance. Currently, only the VKN and TCKN codes are sent, while other required codes are not supported. Desired behavior after PR is merged: Official codes are added as non-deletable tags (non-mandatory ones archived). An error is raised when required tags are missing or empty. Invoices cannot be sent to Nilvera without valid codes. Codes are always reflected in both PDF and XML. [IMP] l10n_tr_nilvera: support for official information codes Added codes as tags from the official list and archived non-mandatory ones. These tags cannot be deleted, and an error is shown on attempt. Invoices are blocked from being sent to Nilvera if either MERSISNO or TICARETSICILNO is missing, or if assigned but without a value. Codes are reflected in both PDF and XML. task-4992049 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223931 Forward-Port-Of: odoo/odoo#223182
UAE payroll calculations now better support contracts based on attendance or planning schedules. This helps produce more accurate payslips for employees whose pay depends on worked time or planned shifts, with added tests to reduce regression risk.
Original PR description
Updates for the salary rules to accomodate Attendance and Planning-based contracts and test cases for said scenarios opw-[4873312](https://www.odoo.com/odoo/all-tasks/4873312) Forward-Port-Of: odoo/enterprise#93765 Forward-Port-Of: odoo/enterprise#90407
Resolved issues and error corrections
The point of sale now correctly asks for the customer's name when a default order preset, such as takeout, requires it. This prevents staff from creating orders without required customer details and keeps restaurant workflows consistent.
Original PR description
Steps to reproduce: - go to the setting of your pos.config - set the default preset as takeout (or any other that require the name) - open your pos - click on new order - the slot selection opens (only if set so it's ok) - but then no dialog to enter the name of the client Issue: The handleSelectNamePreset method in the POS Restaurant module attempts to access the selected preset through the order, but the preset has not yet been set on the order at that point. Fix: Make sure the preset is set on the order before calling handleSelectNamePreset. Task-5030520 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
The point of sale now prevents users from moving to payment until a discount has fully applied. This avoids incorrect payment amounts being sent to payment terminals when discount processing is delayed.
Original PR description
pos*: point_of_sale, pos_restaurant Before this commit, if a discount was applied with the blackbox, it was applied after communication with blackbox which could be slow. If the user was clicking payment before this disound was applied and had only one payment method, a payment line with the old amount was added which could lead to confusion and errors when this payment line was sent to a terminal. This is fixed by waiting for the discount to be applied before being able to click on payment. Enterprise PR: https://github.com/odoo/enterprise/pull/91256 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221020
The self-order kiosk now respects the specific product variants configured for combo items, so customers only see the intended choices. This prevents unintended variant options and extra charges from appearing during combo ordering, while keeping normal variant selection unchanged where appropriate.
Original PR description
**Problem:** When we have a combo product that has a variant product, if we order it from the Kiosk, all the variants for that product will be displayed. The extra price will also be added, even…
**Problem:** When we have a combo product that has a variant product, if we order it from the Kiosk, all the variants for that product will be displayed. The extra price will also be added, even though it is not specified on the combo definition. **Steps to reproduce:** - Create a combo that has a variant product (like aluminium chair) - Go to the Kiosk and order said combo - In the combo page, click on the variant, all the possible variants are displayed **Why the fix:** When creating a combo, we should specify which product variant we want, so that only those are displayed on the combo selection page. The way it is done right now, every variant is displayed whether we want them or not, without a way to refrain them from being displayed. After this commit, if the variants are specified on the combo, only those are displayed in the Kiosk once we click on the combo. If we specify a product that has variants in the combo, all variants will still be displayed when clicking the product in the Kiosk, as it was before. opw-4924019
This fixes a checkout issue where customers could see a server error when the cart page was accessed through a configured URL redirect. The checkout progress display now correctly recognizes redirected cart URLs, improving reliability for websites using custom or rewritten shop links.
Original PR description
Steps: - create a 308 rewrite from /shop/cart to /test/cart - go to /shop/cart Result: An error 500 is shown with this traceback in server log: odoo.addons.base.models.ir_qweb.QWebException: Error while render the template KeyError: 'current_step' Template: website.step_wizard Path: /t/div/div[1]/div/div/a/span Node: <span t-field="current_step.name"/> Cause: The code of website()._get_checkout_step_values doesn't take into account possible URL rewrite, so we get an error when showing website.step_wizard template that expect to have found a current_step. Fix: use url_rewrite to match the current URL to the current step and use the step_href of the step as current_website_checkout_step_href to have it not rewritten. Note: without the fix, the added test fail with the error shown above. opw-5037289
Installing Accounting with German localization and demo data could fail because cleanup of demo accounting records was blocked by the audit trail protection. This update allows that expected cleanup during chart template unloading, so setup can complete without compromising normal audit trail safeguards.
Original PR description
When installing the Accounting app on a new database created with Germany as country and with demo data loaded, the demo loader invokes in `account/demo/account_demo.xml` the `<function name="try_loading">` call which does a wholesale `records.with_context({MODULE_UNINSTALL_FLAG: True}).unlink()`. This cascades into deleting mail.message records, but the audit‑trail hook in only bypasses its check when the `bypass_audit` token is present not when `MODULE_UNINSTALL_FLAG is set causing a “You cannot remove parts of the audit trail” UserError.
Steps to reproduce:
- Created new database, with Germany as country
- Install l10n_de
- Download demo data
- Attempt to install Accounting application ! Receive error message
OPW- 4712364
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#221260Swiss companies can now see the expected domestic taxes when setting up tax replacement rules. This fixes a localization issue where Switzerland's domestic fiscal position was not recognized because it was defined by country group rather than country.
Original PR description
#### Issue: No taxes appear in the replace field when creating a new tax in a company based in Switzerland. #### Step to reproduce: - In a company based in Switzerland (l10n_ch) - Create a new tax -…
#### Issue: No taxes appear in the replace field when creating a new tax in a company based in Switzerland. #### Step to reproduce: - In a company based in Switzerland (l10n_ch) - Create a new tax - Add a Fiscal position other than "Switzerland national (+ Liechtenstein)" - Click on the "Replace" field #### Current behavior: - No records are found #### Expected behavior: - Taxes from the "Switzerland national (+Liechtenstein)" fiscal position should appear #### Cause of the issue The Replace field display domestic taxes. Domestic taxes are part of the same fiscal position which is computed as domestic. In the l10n_ch module no fiscal position is computed as `domestic_fiscal_position_id`. Indeed in `account.fiscal.position-ch.csv` the fiscal position we want to be domestic is linked to a `country_group_id`, but no `country_id`. However the domestic fiscal position is computed from `country_id` only. Therefore Switzerland has no `domestic_fiscal_position_id`. #### Solution: This issue already happened [once](https://github.com/odoo/odoo/pull/208810) for an other localization. To avoid the situation to happen again in the future this commit adapts the `_compute_domestic_fiscal_position_id` to include fiscal position with no `country_id` but a `country_group_id`. opw-5011527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Importing a contact after removing its company from an exported file no longer silently overwrites an existing linked contact in a way that breaks parent-child relationships. This protects contact data consistency and helps avoid downstream errors in other business processes that rely on correct company/contact links.
Original PR description
_______________________________________ ## Short functional explanation of the error Let's say that you have a contact of type Company and a child contact of type Individual. Both share the same…
_______________________________________ ## Short functional explanation of the error Let's say that you have a contact of type Company and a child contact of type Individual. Both share the same company_id. But when exporting the individual, deleting its company in the downloaded .xlsx file and importing it again, it overrides the already existing individual, resulting in a single individual contact without company_id nor parent company. However, the contact of type company will still have the individual as its child, creating an inconsistency. This leads to errors in other modules as the rules aren't respected by these records anymore. ## Reproduction Steps 1. Go to the contact application and create a contact of type Company. Set an email and click on the Sales and Purchase tab and set a Company. 2. Go back to the Contacts tab and click on add contact. Click the radio button Contact, set an email and hit Save and Close. 3. Go back to the Contacts app. You should see 2 more contacts: one corresponding to the company and one corresponding to the individual. 4. Select the Individual contact and click Actions > export. Check 'I want to update data (import-compatible export)' and on the left panel, click on the + button next to Company. Then, click export. 5. Click on the file it generates and remove the company, then save. 6. Click on the cog next to Contacts on the top left and click Import Records. Then, click on Upload Data file and select the file you just exported. You should see that the field company_id has no value. Click Test then Import. ### Expected behavior Either an error message should show up or the link between the Company contact and its child should be removed. ### Unexpected behavior The individual contact containing the link to its parent Company contact is overridden by the contact we just imported, which doesn't have a link to the parent company contact. However, the company contact conserves a link to the child individual contact. This means that one way of the 2-ways link has been deleted, creating an inconsistency. ## Origin of the issue We can override res.partners using the names and email addresses, which are primary keys, but the code doesn't check the consistency of parent/ children links. _________________________________________ opw-4976400 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The point of sale now waits until a blackbox discount is fully applied before allowing the cashier to proceed to payment. This prevents payment lines from being created with an outdated amount, reducing cashier confusion and potential terminal payment errors.
Original PR description
Before this commit, if a discount was applied with the blackbox, it was applied after communication with blackbox which could be slow. If the user was clicking payment before this disound was applied and had only one payment method, a payment line with the old amount was added which could lead to confusion and errors when this payment line was sent to a terminal. This is fixed by waiting for the discount to be applied before being able to click on payment. Community PR: https://github.com/odoo/odoo/pull/221020 Forward-Port-Of: odoo/enterprise#91256
Fixes an issue where Chilean companies could see the Point of Sale crash when validating an order if a receipt field was not configured. Receipts now skip that optional field when it is missing, allowing sales to complete normally.
Original PR description
Currently, when having a CL Company an dusing the POS, it is possible to have the POS crash when validating orders. Steps to reproduce: ------------------- * Install l10n_cl_edi_pos * Create a new…
Currently, when having a CL Company an dusing the POS, it is possible to have the POS crash when validating orders. Steps to reproduce: ------------------- * Install l10n_cl_edi_pos * Create a new company * Put Chile as country * Switch to that company * Create a shop and open it * Make a sale, validate order > Observation: POS Crashes Why the fix: ------------ The crash is happening upon trying to render the receipt because `l10n_cl_dte_resolution_date` is undefined. `l10n_cl_dte_resolution_date`is a field that can be found on the company settings only if the field `l10n_cl_dte_service_provider` is set and is required when the later has either `SII` or `SIITEST` as value. For companies in Chile, there is therefore two setups that leads to having `l10n_cl_dte_resolution_date` undefined. Either the service provider is set to demo, which case clients don't need to fill in the resolution date, either the provider is left empty (since not required upon company creation). Since the field can be undefined, we don't render it when it is. opw-5034091
Danish Intrastat and EC Sales List reports now round required figures to whole units for official submissions, helping meet government reporting expectations. Users can still view decimal values in the interface when needed, while exported files are consistently rounded.
Original PR description
This commit will change the options of the reports so that we have a rounding in units since the intrastat and ec sales list report must be rounded. This solution still allows people to have the report with decimals if needed task-4948271 Forward-Port-Of: odoo/enterprise#93783 Forward-Port-Of: odoo/enterprise#91268
This fix prevents portal users from becoming owners of Documents spreadsheets because they cannot receive edit access to spreadsheets. It keeps ownership aligned with valid internal users, reducing access and workflow issues around shared spreadsheets.
Original PR description
Following the discussion I had with @flch-odoo regarding https://github.com/odoo/enterprise/pull/92134 , Since Spreadsheets can not be shared in edit mode to non-internal users, we prevent them from becoming owners. opw-4753670 Forward-Port-Of: odoo/enterprise#93800 Forward-Port-Of: odoo/enterprise#92409
Closing an AI chat before the assistant finishes responding no longer creates a new chat with the delayed reply. This prevents unexpected conversations from appearing and keeps the chat experience consistent for users.
Original PR description
If a user sends a message to an ai agent and then closes the chat channel before receving the response, a new ai chat channel gets created and the response is posted to that channel. Cause of the Issue : When the channel is deleted, a serialization error occurs because one transaction is trying to delete the channel while the other is trying to post the ai response to the channel. The delete transaction finishes execution and the response generation transaction is retried. When generate_response is retried, _get_or_create_ai_chat is called and given that the old channel has already been deleted, a new one is created and the response is posted to that channel. task-5063221