Daily updates from Odoo
Friday, September 5, 2025
20 changes · 18.0
New functionality added to Odoo
A new payment button on the Point of Sale ticket screen lets staff go directly to payment without first reopening the order. This reduces extra steps during checkout and can make in-store service faster.
Original PR description
In this Commit: - Added a payment button on the ticket screen to go directly to the payment screen, instead of loading the order first and then navigating to the payment screen. 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
Attendance approvers now get a read-only view in the Work Information section of My Profile when employees are not allowed to edit their own data. This keeps approval-related information visible while respecting company controls over employee profile edits.
Original PR description
Add read-only mode for the attendance approver in the My Profile Work Information tab when `allow employee to edit own data` is disabled. task-5008352 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
HDFC batch payment files now use the bank’s required transaction codes, date format, and file layout. This reduces the risk of rejected payment uploads while preserving existing header behavior and configuration flexibility for other banks.
Original PR description
- Updated the HDFC bank template to match the required file structure. The transaction type is now based on the payment method code instead of its display name, with explicit mappings to HDFC codes
(RTGS → R, NEFT → N, Fund Transfer → I, Demand Draft → D).
- Relabel the `date` field and export it using the format `%d/%m/%Y` for HDFC Bank Template.
- During CSV export, the header row is skipped when generating files for HDFC, while other banks continue to include it.
- Improve CSV export behavior:
- For HDFC, the header row is skipped.
- For other banks, headers remain included.
- Apply field-level mappings and date formatting defined in the bank configuration.
These changes ensure that batch payment exports comply with bank’s file specifications while keeping the solution flexible for other templates.The Budget Report now uses the analytic plan name, such as Project, instead of the generic label Account when grouping information. This makes the report easier for customers to understand and reduces confusion when reviewing budgets.
Original PR description
In this commit: - Change the group by label from `Account` to the analytic plan's name (`Project`) for clarity in the Budget Report. This improves customer understanding and reduces confusion. task-5045530
Resolved issues and error corrections
The Unsplash image search now handles duplicate images returned in the same search results. This prevents users from seeing an error when selecting images, such as during searches where Unsplash sends repeated results.
Original PR description
This commit fixes an OwlError when we try to render the images received from Unsplash after a search. The issue is that Unsplash can send duplicate images in the same batch of images. When we render those in a `t-foreach` and use the image `id`s as the keys, we get a duplicate key error. This is fixed by expanding on the previous filtering code, which ignored duplicates over multiple batches. We now ignore duplicates within batches as well. At the time of writing, Unsplash is sending us duplicate images on a search for "Inventory". opw-5027032 P.S., this is really just an extension of this PR here #224059. Specifically, the 18.0 FW. In 18.0, the Unsplash code that I changed in the original PR (#223789) was moved from `addons/web_unsplash/static/src/components/media_dialog/image_selector.js` to `(...)/components/media_dialog_legacy/image_selector.js`. This PR fixes the "copy" of that code that got moved.
Analytic line amounts now use the company currency rounding instead of the foreign currency rounding. This prevents misleading totals when foreign currencies have coarser rounding rules, improving accuracy for accounting review and reporting.
Original PR description
Steps to reproduce: - set the rounding of a foreign currency to 1.0 - have you company currency's rounding to 0.01 - create a move with a line with an analytic distribution - post it - go to analytic line Issue: The amount will be displayed with a rounding of 1.0 and not 0.01 opw-4997047
This update brings the spreadsheet component to its latest version and fixes several issues affecting spreadsheet imports, pivot data, formulas, borders, and calculations. Users should see fewer errors when opening Excel files, working with pivot-based data, or using formulas in spreadsheets.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/0f02dde52 [REL] 18.0.43 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/0f02dde52 [REL] 18.0.43 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/e093ffbd5 [FIX] menu_items: fix sequence calculation for pivot data sources [Task: 5025230](https://www.odoo.com/odoo/2328/tasks/5025230) https://github.com/odoo/o-spreadsheet/commit/e726d26b0 [FIX] xlsx: make import verbose [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/f3f585058 [FIX] evaluation: fix operation with empty matrices [Task: 5001658](https://www.odoo.com/odoo/2328/tasks/5001658) https://github.com/odoo/o-spreadsheet/commit/14a6da6d6 [FIX] xlsx: cannot import CF with formulas [Task: 4945945](https://www.odoo.com/odoo/2328/tasks/4945945) https://github.com/odoo/o-spreadsheet/commit/97ccf4cb0 [FIX] pivot: handle vectorized formula [Task: 5043187](https://www.odoo.com/odoo/2328/tasks/5043187) https://github.com/odoo/o-spreadsheet/commit/ea7ea0abe [FIX] borders: Recompute borders on `SET_BORDERS_ON_TARGET` [Task: 5024825](https://www.odoo.com/odoo/2328/tasks/5024825) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
The Veri*Factu regime key dropdown on Spanish invoices now shows the expected options. This helps users complete compliant Spanish e-invoicing workflows without being blocked by an empty selection field.
Original PR description
### Issue: The dropdown for the regime key doesn't show any value, even when it's supposed to. ### Steps to reproduce: - Install "l10n_es_edi_verifactu" and switch to a Spanish company - Create an invoice for a Spanish partner with the tax "21% G (Goods)" for example - In the page "Veri*factu" the field "Veri*Factu Regime Key" has a dropdown but no values to choose from ### Cause: This field uses the widget `dynamic_selection` which applies a filter on the possible values of the selection. This filter is simply the field `l10n_es_edi_verifactu_available_clave_regimens` which is computed from the list of possible values and the tax_ids on the invoice. As this field is computed and non stored but do not appear in the view, it is never recomputed, so the dropdown shows no values. ### Solution: Add the field in the view, and make it invisible. opw-5039271
When invoices are created for a child contact, Odoo now checks the parent company’s preferred invoice sending method. This prevents invoices from being sent by email when the company is configured to use Peppol, improving consistency for customers with multiple contacts.
Original PR description
**Steps to reproduce** - Have a partner with Invoice Sending configured 'by Peppol' - Create a child contact for that partner - Make 2 invoices for the child contact - Select both and click 'Send' **Issue** The system will try to send invoice by mail, even if Peppol is correctly setup This occurs because when retrieving the default sending method we only look at the partner of the move, that, being a child contact, does not have invoicing info opw-4925876
This fix ensures that when a customized view removes an element and adds text in the same area, the added text is correctly displayed. It prevents missing text in inherited templates when branding/debug metadata is enabled, improving reliability for customized Odoo screens.
Original PR description
With the inherit branding activated, have a xpath in an inherited view that removes a node, and adds some text afterwards in the parent of the removed node Before this commit, the text of the spec was not output. This was because it was appended to the removal ProcessingIntruction that was removed later on After this commit, a spec can add text in a node from which a child has been removed 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#223576
This fixes an issue where adding a prepaid service line to an already confirmed sales order showed a zero cost instead of the product's configured cost. The correction helps keep sales margins accurate when orders are updated after confirmation.
Original PR description
…O confirmation **Problem:** When a service is added on a SO after the confirmation the cost column (purchase_price) is 0 **Steps to reproduce:** - make sure that sale_timesheet_margin is installed - create a service with a positive cost - create a SO for 1 unit of this service - confirm - add a new line on the SO for the same service **Current behavior:** the cost is 0 **Expected behavior:** the cost should be the cost you set on the product form **Cause of the issue:** since this PR https://github.com/odoo/odoo/pull/207228 services that are "ordered_prepaid" on confirmed sale order are filtered out the purchase price computation https://github.com/odoo/odoo/blob/5f6d2afa8c09fe72c01d056ebef01214567a4a99/addons/sale_timesheet_margin/models/sale_order_line.py#L9-L15 opw-5016622
Fixes a website editor crash that could happen when saving links in mega menus using the Cards template. The editor now correctly distinguishes color styling from other text formatting and avoids unsafe format removal on styled buttons, improving editing reliability.
Original PR description
Description of the issue this PR addresses: Issue 1: Steps to Reproduce: - Open the website. - Create a mega menu. - Enter edit mode. - Change the mega menu template to “Cards”. - Click on any option…
Description of the issue this PR addresses: Issue 1: Steps to Reproduce: - Open the website. - Create a mega menu. - Enter edit mode. - Change the mega menu template to “Cards”. - Click on any option available in the mega menu. - A link popover will open. - Click the Edit link button in the popover. - Click the Apply button to save the link. - A traceback occurs. The error occurs because the text-wrap class is applied to the link. When the hasColor method is triggered, it checks whether a.nav-link has a text color class. However, TEXT_CLASSES_REGEX incorrectly matches text-wrap as a color class. As a result, the removeColor method attempts to remove it and triggers _applyColor to remove the color, but in _applyColor method it does not find any color to remove on selected text. As a result, the removeColor process enters an infinite loop, which eventually leads to a traceback. Solution: Update TEXT_CLASSES_REGEX so that it only matches valid text color classes and excludes formatting classes such as text-wrap, text-center, etc. Issue 2: This commit ensures that the remove format action is disabled when a button (.btn element) has custom color or background color applied. Because buttons include padding, there is no proper way to remove a background color from a partially selected button, so the action must be ignored in this case. task-5062715 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an error message that could fail when checking company compatibility on records linked to multiple companies. Users now receive a clear explanation of the incompatible company setup instead of a technical crash, helping them correct accounting or multi-company data issues faster.
Original PR description
`_check_company` can be called on models that don't have a `company_id` field, but they might have a `company_ids` one. In this case the message logged as the user error should be able to handle that…
`_check_company` can be called on models that don't have a `company_id` field, but they might have a `company_ids` one. In this case the message logged as the user error should be able to handle that scenario.
Example on how to reproduce the error in accounting:
```py
company_a, company_b
tax_group self.env["account.tax.group"].create(
{
"name": "Tax Group",
"company_id": company_a.id,
}
)
tax = self.env["account.tax"].create(
{
"name": "30% - Loan Tax",
"type_tax_use": "sale",
"tax_exigibility": "on_payment",
"amount": 30,
"amount_type": "percent",
"tax_group_id": tax_group.id,
"company_id": company_a.id,
}
)
account = self.env["account.account"].create({
...,
"company_ids": [Command.link(company_b.id)]
})
account.tax_ids |= tax
```
Error raised
```
AttributeError: 'account.account' object has no attribute 'company_id'
```
After the PR the following message appears:
```
odoo.exceptions.UserError: Incompatible companies on records:
- “Loan Principal” belongs to company “BE Company Loan Tests” and “Default Taxes” (tax_ids: '30% - Loan Tax') belongs to another company.
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#225177This fixes a rounding issue where loyalty discounts could use slightly more points than intended because of currency calculation precision. Customers and businesses now see loyalty point balances adjusted more accurately after sales orders are confirmed.
Original PR description
## Version
18.0+
## Issue
A slightly higher number of loyalty points might be used when python division can't be precise enough.
## Steps to reproduce
- Create a new Discount & Loyalty program:
- Program Type: Loyalty Cards;
- Conditional rules: None;
- Rewards: 1:
- Reward Type: Discount;
- Discount: 0.03$ per point on Order.
- Create a new Loyalty Card for any partner (remember which one):
- Change the points balance for 3030.
- Create a new Quotation for the previously selected partner as customer:
- Add a product:
- Use any product;
- Quantity: 1;
- Unit Price: 3000.0;
- Taxes: None.
- Apply the Reward and Confirm the SO;
- Check Loyalty Card's details at the bottom of the SO.
opw-4928963This fixes an error that could prevent gamification challenge report emails from being sent when some expected data was missing. The email template now handles missing values safely, improving reliability for users sending challenge reports.
Original PR description
If we use dict['foo'] in the template and that foo key does not exit, then a key error will be raised but if we use dict.get('foo'), then we can define which default value be returned whether None or ''.
Calling dict['foo'] or '' is no longer valid in python3.11, but better to use get method.
Steps to reproduce bug:
1: Create a challenge for gamification.challenge model
2: Set 'Display Mode': "Indiviual Goals"
3: Set any simple goal, set other required fields
4: Click on "Start Challenge" button
5: Click on "Send Report" button
Observation:
The mail xml template will fail to render and raise server error.
Solution:
Use get method to call the dictionary key value to safeguard.
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-prOdoo now handles missing SEPA pre-notification settings during module reinstallation, preventing an error when batch payments use SEPA Direct Debit. This keeps installation and reinstallation flows stable for companies using SEPA payment processing.
Original PR description
**Issue** When creating a batch payment with SEPA Direct Debit as payment method, if the user uninstalls the SEPA module and then installs it again, Odoo raises a `TypeError: 'int' object is not…
**Issue**
When creating a batch payment with SEPA Direct Debit as payment method, if the user uninstalls the SEPA module and then installs it again, Odoo raises a `TypeError: 'int' object is not iterable`.
**Steps to Reproduce**
1. Create a batch payment with SEPA Direct Debit.
2. Uninstall the `account_sepa_direct_debit` module.
3. Reinstall the module.
**Root Cause**
During module (re)installation, the compute method `_compute_sdd_required_collection_date` is triggered before any SEPA mandates or their pre-notification periods exist. This makes `mandates.mapped('pre_notification_period')` return an empty list. The code then calls:
max(minimum_offset, *mandates.mapped('pre_notification_period'))
When the list is empty, this reduces to `max(minimum_offset)`, which is invalid since `max()` with a single integer argument expects an iterable and raises a `TypeError`.
**Fix**
Handle the empty case so that there is a valid fallback both during installation and when mandates have no configured pre-notification period.
Opw-5042153Fixed an issue where adding many spreadsheet lists could cause related menu options to appear in the wrong place. This keeps spreadsheet menus organized and easier for users to navigate when working with many lists, pivots, or charts.
Original PR description
Steps to reproduce: - Add 25 lists in a spreadsheet => The order of the lists is not correct, menu items like "Re-insert static pivot" are positioned inside the list items. This commit fixes the sequence computation of the menu items for the pivots, lists and charts in spreadsheet to always be inside one integer (from 50 to 51 for pivots, 53 to 54 for lists, ...). Task: 5025230
Spreadsheet menus now keep list, pivot, and chart actions grouped in the correct order, even when many lists are added. This prevents unrelated actions from appearing in the middle of list entries, making the spreadsheet menu clearer and easier to use.
Original PR description
Steps to reproduce: - Add 25 lists in a spreadsheet => The order of the lists is not correct, menu items like "Re-insert static pivot" are positioned inside the list items. This commit fixes the sequence computation of the menu items for the pivots, lists and charts in spreadsheet to always be inside one integer (from 50 to 51 for pivots, 53 to 54 for lists, ...). Task: 5025230
Customer follow-up reminders now avoid resending the same final reminder every day for invoices that have already been included in that follow-up step. This prevents customers from receiving duplicate overdue invoice emails when there are no new invoices to chase.
Original PR description
**Steps to reproduce:** - Install Accounting - Go to "Accounting / Configuration / Invoicing / Follow-up Levels" - Create a unique follow-up level: * Remind 1 day after due date * Send Email:…
**Steps to reproduce:** - Install Accounting - Go to "Accounting / Configuration / Invoicing / Follow-up Levels" - Create a unique follow-up level: * Remind 1 day after due date * Send Email: [checked] * Automatic: [checked] - Create an invoice: * Customer: [any] * Invoice Date: [1 month ago] * Due Date: [1 month ago] * Invoice Lines: [any] - Confirm the invoice - Go to "Settings / Technical / Automation / Scheduled Actions" - Open "Account Report Followup; Execute followup" - Run it manually => A reminder is correctly sent to customer (i.e. message on partner record) - Wait for the following day - Run the scheduled action again **Issue:** The same reminder in sent again. The last reminder will be sent every day even if there is no new invoice. **Cause:** When computing the follow-up status for a contact, all the entries that are due are taken into account. The entries that have already been included in a follow-up should be ignored when computing the same follow-up again. **Solution:** A field on a journal item (i.e. followup_line_id) tracks in which follow-up level the item has been included. We can exclude the journal items that has this field set to the next follow-up level. opw-4964103 Forward-Port-Of: odoo/enterprise#94000 Forward-Port-Of: odoo/enterprise#92191
Miscellaneous changes
Description of the issue/feature this PR addresses: - When a user cancels a filter on a burndown chart, if stageIdSearchItemId is undefined, an error is raised. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#197126 Forward-Port-Of: odoo/odoo#170510
Original PR description
Description of the issue/feature this PR addresses: - When a user cancels a filter on a burndown chart, if stageIdSearchItemId is undefined, an error is raised. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#197126 Forward-Port-Of: odoo/odoo#170510