Daily updates from Odoo
Tuesday, September 16, 2025
55 changes · saas-18.4
Security fixes and vulnerability patches
Budget report entries are now limited to the companies the user is currently allowed to access. This prevents users from seeing budget data from other companies and avoids confusing access errors when opening those entries.
Original PR description
**Steps to reproduce:** - Install Accounting - In Accounting settings, activate "Budget Management" - Go to "Accounting / Accounting / Analytic Budget" - Create a budget - Open the budget - Create a bill (or invoice depending on the budget type) using the analytic used in the budget lines - Create a budget from another company and also a bill using the analytic used in the budget lines - Connect with a user with Accounting rights who only has access to the first company - Go to "Accounting / Reporting / Management / Budget Report" - Switch to the list view - Remove the "Open Budget" filter **Issue:** The entries linked to the budget from the other company are visible. When trying to open one of them, an access error is raised. **Solution:** Add a multi-company record rule for budget report. opw-4943360 Forward-Port-Of: odoo/enterprise#94105
Enhancements to existing features
Italian fiscal position rules now distinguish services from goods more clearly. This prevents a single product tax from being replaced by multiple zero-rate EU taxes, helping invoices apply the correct tax treatment.
Original PR description
Due to service taxes missing from the domestic fiscal position, when using the base tax on a product and the intracom fiscal position, it is mapped to both the 0% EU G and 0% EU S taxes. This happens with multiple taxes. By adding service taxes and splitting the mapping from default to goods and from services to services, the fiscal position only ever applies one tax per origin. task-none Forward-Port-Of: odoo/odoo#226529
This update adds automated checks for point-of-sale event registration, ticket selection, and event product creation. These tests help ensure event-related sales flows continue to work correctly as the system evolves, reducing the risk of regressions for businesses using events in POS.
Original PR description
In this commit: ------------ - We are adding hoot test cases to verify that components return values according to the passed parameters for components like `event_configurator_popup`, `event_registration_popup`, and `event_slot_selection_popup`. - Also, we are adding a test for the `addProductToOrder` method available in the `product_screen` component to ensure the order line is added to the order seamlessly. - Then, we are adding a test for the `createDummyProductForEvents` method available in the `pos_store` service to verify that the products are created for all the loaded events in the POS. task-4945631 Forward-Port-Of: odoo/odoo#220734
GST return reconciliation now more reliably matches draft and cancelled vendor bills using valid invoice references or IRNs. This reduces missed matches and helps businesses prepare more accurate GST-2B reconciliations during return periods.
Original PR description
Before this PR: - `line_ids.tax_ids` filter was applied too early, excluding some valid draft/cancelled bills. - Bill reference and IRN checks were not consistently combined, leading to missed matches in reconciliation. - Posted bills could be incorrectly excluded when the reconciliation status was not considered properly. After this PR: - Refined domain grouping so `line_ids.tax_ids` and GST treatment checks only apply for posted bills. - Draft/cancelled bills are matched if they have a valid IRN or bill reference. - Posted bills require bill reference, tax, reconciliation status, and GST treatment checks for accurate matching. This ensures more reliable matching of draft bills with GST-2 B during the GST return period reconciliation. Forward-Port-Of: odoo/enterprise#94384
Resolved issues and error corrections
Studio exports now work correctly for binary fields that are not stored as attachments. This prevents export failures and helps users retrieve their Studio-managed data reliably.
Original PR description
**Before:** Attempting to export non-attachment binary fields using the `Studio Export` would cause a traceback. **After:** Non-attachment binary fields can now be successfully exported from `Studio` without error. task-4888937 Forward-Port-Of: odoo/enterprise#94230 Forward-Port-Of: odoo/enterprise#93781
DIN5008 report layouts now stop showing the customer's phone number in the address block, and the customer's VAT number is moved out of that section. This keeps printed customer addresses cleaner and aligned with the intended DIN5008 layout.
Original PR description
This commit removes the phone number from the DIN5008 report layout. The customer's VAT is also no longer displayed in the customer's address section. The VAT is moved to another section. Description of the issue/feature this PR addresses: Current behavior before PR: The customer's phone number and VAT are displayed in the customer's address in the DIN5008 report layout. Desired behavior after PR is merged: The customer's phone number is no longer displayed and VAT moved to another section in the DIN5008 report layout. opw-5049074 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226967 Forward-Port-Of: odoo/odoo#226630
This fixes an issue where loyalty points could be counted twice after a sales order was confirmed, preventing some eligible discounts from being applied. Businesses using discount and loyalty programs can now expect customers to receive all qualifying rewards consistently.
Original PR description
## Versions: 16.0+ ## Issue: After confirming a Sales Order (SO), loyalty points are incorrectly calculated when applying additional promotions. This causes only one reward to be applied instead of…
## Versions:
16.0+
## Issue:
After confirming a Sales Order (SO), loyalty points are incorrectly calculated when applying additional promotions. This causes only one reward to be applied instead of all eligible ones.
## Cause:
When the SO is confirmed, the cost in points for each line is retrieved and deducted to compute remaining available points. However, when promotions are re-applied, the system re-evaluates the total cost of the SO and deducts the points again, effectively double-counting the same lines.
## Steps to reproduce:
- Set up a `Discount & Loyalty` promotion program:
- 2 points granted per purchase (minimum $0).
- Rewards:
- 5% discount on "Simple Pen" (costs 1 point).
- 10% discount on "Whiteboard Pen" (costs 1 point).
- Create a Quotation with "Simple Pen" and "Whiteboard Pen".
- Confirm the Quotation into a Sales Order.
- Apply promotions:
- The first reward applies correctly
- The second reward does not apply
opw-4753472
Forward-Port-Of: odoo/odoo#226656
Forward-Port-Of: odoo/odoo#211342Users can now add several new comma-separated tags when creating a forum post without triggering an error. This prevents failed post submissions and makes forum tagging behave as expected.
Original PR description
Currently, an error occurs when a user tries to add multiple comma-separated new tags to a forum post. **Steps to reproduce:** - Install the `website_forum` module. - Go to: `Website > Configuration…
Currently, an error occurs when a user tries to add multiple comma-separated new tags to a forum post. **Steps to reproduce:** - Install the `website_forum` module. - Go to: `Website > Configuration > Forums`, create a new forum, then click `Go to Website`. - Click on `Start by creating a post`, enter content, and set the `Tags` to `_test, retour affectif rapide`. - Click on `Post Your Question`. **Error:** `ValueError: invalid literal for int() with base 10: 'retour affectif rapide'` **Root Cause:** After PR #169472, at [1], the code prepends an underscore (_) only to the entire input string instead of each tag. When multiple tags are entered, the backend receives a mixed list of values (e.g., ['__test', 'retour affectif rapide']), leading to an error during `int()` conversion at [2]. **Fix:** This commit updates the `onCreateOption` logic to prepend an underscore to each tag in the comma-separated input, similar to [3]. Also updated the test case at [4], to click `Create option` to save the tags. [1]: https://github.com/odoo/odoo/blob/afa26af132566a68ad6bf67565062bd73ddd7429/addons/website_forum/static/src/js/website_forum.js#L54-L61 [2]: https://github.com/odoo/odoo/blob/afa26af132566a68ad6bf67565062bd73ddd7429/addons/website_forum/models/forum_forum.py#L304 [3]: https://github.com/odoo/odoo/blob/ac93a25b216e6194895a64fe12c0d01f6833f743/addons/website_forum/static/src/js/website_forum.js#L69-L80 [4]: https://github.com/odoo/odoo/blob/d155edfd729ab9b53f38939fe24b6d1e7b578083/addons/website_forum/static/tests/tours/website_forum_question.js#L34-L37 sentry-6761920887 Forward-Port-Of: odoo/odoo#227185 Forward-Port-Of: odoo/odoo#220058
The accounting KPI summary now counts posted accounting entries that still need an accountant's review, in addition to draft entries. This gives teams a more complete view of outstanding accounting work and categorizes it by journal type for clearer reporting.
Original PR description
The `kpi.provider:get_account_kpi_summary` method should count draft moves by category, but also include posted moves that still are to be checked by the accountant. Task-id: 5062431 Forward-Port-Of: odoo/odoo#227091 Forward-Port-Of: odoo/odoo#226411
PDF documents now display tiny negative amounts that round to zero as "0.00" instead of "-0.00". This avoids confusing or misleading totals on printed reports and customer-facing documents.
Original PR description
Previously, when an amount value that is passed to `value_to_html` is a really small negative number (e.g. -0.000000001), the rounded result will have the negative sign in front of it (e.g. "-0.00").
This commit fixes it so that they will be rendered without the negatives ("0.00").
opw-4685953
Forward-Port-Of: odoo/odoo#224292This fix prevents the Time Off app from showing an error when a user clears the end date while creating a leave request. The system now safely skips date comparison until valid dates are entered, keeping the form usable and relying on existing validation to guide the user.
Original PR description
Currently, an error occurs when user removes value from `request_date_to` field. **Steps to replicate:** - Install Time Off app and open it. - Click new and remove values from the `request_date_to` field (the second date field in the row) and click somewhere else. **Error:** `TypeError: '<=' not supported between instances of 'datetime.date' and 'bool'` **Cause:** - The field `leave.request_date_to` is received as `False` in the line [1] as the user deleted it. **Solution:** - Added a check for date values, if the date values are false, the further code execution is skipped because the validation is already present. [1]: https://github.com/odoo/odoo/blob/b6c4c190331a7dc826df1b2ef399c0f6be32f657/addons/hr_holidays/models/hr_leave.py#L363 sentry-6830356042 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Employees with more than one running contract can now open the Time Off app without an error. This fix helps HR teams manage employees whose contracts change during the year without disrupting leave planning.
Original PR description
**Step to Reproduce** - install hr_contract and hr_holidays module - go to employee -> contracts - Add 2-3 contract to a employee, which can be done by having contracts in different interval (but…
**Step to Reproduce**
- install hr_contract and hr_holidays module
- go to employee -> contracts
- Add 2-3 contract to a employee, which can be done by having contracts in different interval (but same year)
- set their stage to `running`
- open Time off App
**Observation:**
- we receive a traceback
```
File "/data/build/odoo/addons/hr_contract/models/hr_employee.py", line 229, in _get_unusual_days
tmp_date_from = max(date_from_date, selected_contract.date_start)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/odoo/odoo/orm/fields.py", line 1424, in __get__
record.ensure_one()
File "/data/build/odoo/odoo/orm/models.py", line 5635, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: hr.contract(1, 2)
```
**Cause:**
- `_get_unusual_days` assumes that there is only one running contract
- Hence with multiple contract, it raises traceback
Fix:
- Adjust the method to accept multiple contracts
opw-5045306
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#225521This fix prevents calendar events with non-Odoo video call links from failing during upgrades or mail template checks. It ensures Google Calendar permission validation only applies when relevant calendar-sync fields are being changed, reducing disruption for users upgrading databases with appointments and Google Calendar enabled.
Original PR description
**Steps to Reproduce:** 1. Create DB in 18.0 with calendar module and google_calendar without demo data. 2. create a calendar event with videocall location other then odoo generated and mark that as…
**Steps to Reproduce:**
1. Create DB in 18.0 with calendar module and google_calendar without demo data.
2. create a calendar event with videocall location other then odoo generated and mark that as guest_readonly.
3. after that install appointment module and ``acces_token``.
4. upgrade to 18.3 below mentioned traceback will raise or can update to mail template.
**Issue**
why from 18.3 [from](https://github.com/odoo/odoo/commit/999df6d4a3b5d21648e5e09757661714e99e1154#diff-bd520efea06a5449c8694b54f5f7aa8587c929a5669ea0439bb9d5e38f8d29c8) this commit now template will render on record for checking. During render checking the ``videocall_redirection`` field value as it [compute](https://github.com/odoo/enterprise/blob/f5d99ea7ae7c2748c4a23a793c46ab1a123b3aad/appointment/models/calendar_event.py#L188) and non store field it going for compute over here the access_token is missing so it will go for compute and during that this [validation](https://github.com/odoo/odoo/blob/1ac89eb71aab48fa8d50fbae01d96bec23d88418/addons/google_calendar/models/calendar.py#L106) is triggering and it breaking because env user is odoobot and user_id is different this issue occur during checking on write on mail template.
**Fix:**
For fixing this checking is the fields syncable with calendar or not
```
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields.py", line 1751, in __get__
self.compute_value(recs)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields.py", line 1914, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/saas-18.4/addons/calendar/models/calendar_event.py", line 696, in _compute_field_value
return super()._compute_field_value(field)
File "/home/odoo/src/odoo/saas-18.4/addons/mail/models/mail_thread.py", line 469, in _compute_field_value
return super()._compute_field_value(field)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/models.py", line 4620, in _compute_field_value
determine(field.compute, self)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields.py", line 81, in determine
return needle(*args)
File "/home/odoo/src/enterprise/saas-18.4/appointment/models/calendar_event.py", line 207, in _compute_videocall_redirection
event.access_token = uuid.uuid4().hex
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/fields.py", line 1847, in __set__
records.write({self.name: write_value})
File "/home/odoo/src/enterprise/saas-18.4/appointment/models/calendar_event.py", line 246, in write
res = super().write(vals)
File "/home/odoo/src/odoo/saas-18.4/addons/google_calendar/models/calendar.py", line 96, in write
self._check_modify_event_permission(values)
File "/home/odoo/src/odoo/saas-18.4/addons/google_calendar/models/calendar.py", line 108, in _check_modify_event_permission
raise ValidationError(_("The following event can only be updated by the organizer "
odoo.exceptions.ValidationError: El organizador es el único que puede actualizar el siguiente evento de acuerdo con los permisos del evento establecidos en Google Calendar.
```
opw-5042454
upg-3113613
TBG - 2082
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#226890Lists marked to appear without indentation now keep their intended spacing in the website editor. This prevents footer and other unstyled lists from looking incorrectly indented while editing pages.
Original PR description
Problem: The default Bootstrap padding is being forced on all lists inside the editor, including those with the `list-unstyled` class. This class is supposed to enforce `0px` padding, but the current rule overrides it. Solution: Remove the style as `2rem` is already the Bootstrap default list padding. Done here: https://github.com/odoo/odoo/commit/1593f25b0160a68d356dd5bba3887ff5a6298c60 Steps to reproduce: 1. Open website. 2. Open the editor. 3. Notice the footer list (with `list-unstyled`) is incorrectly indented. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227204
Creating a repair order with a kit product no longer triggers an error. This restores the expected repair workflow for businesses that service or repair bundled products.
Original PR description
**PROBLEM** There is a traceback when trying to create a repair order with a kit product. **CAUSE** Commit https://github.com/odoo/odoo/commit/facf4eba6cd0504aae949c23454c6ffa9eaa9c3f removed `name` field on `stock.model`, but forget one occurence in `mrp_repair`. opw-5068120
This fixes an internal test setup issue where the self-order payment route was generated before its access token was available. The change helps keep kiosk QR code and IoT payment-related testing reliable, reducing the risk of regressions reaching users.
Original PR description
A call to `_get_self_order_route` in the `test_online_payment_kiosk_qr_code` test was happening too early, resulting on getting the self order url missing the `access_token`. This resulted in making the test fail due to the override of the `iot_http` service in `pos_self_order_iot`, relying on this token to get the IoT WebSocket channel. Enterprise PR: odoo/enterprise#93895
Fixes an issue that could block Ecuadorian delivery guide generation when barcode scanning was turned off in Inventory settings. Businesses can now create delivery guides reliably without needing to enable barcode scanner features.
Original PR description
Currently, an error occurs when generating a Delivery Guide if the Barcode Scanner is disabled in the Inventory settings. **Steps to reproduce:** - Install the `l10n_ec_edi_stock` module and switch…
Currently, an error occurs when generating a Delivery Guide if the Barcode Scanner is disabled in the Inventory settings. **Steps to reproduce:** - Install the `l10n_ec_edi_stock` module and switch to the `EC company`. - Uncheck `Barcode Scanner` in the Inventory `settings`. - Create a new warehouse and set the `Entity` and `Emission Point`. - Navigate to Inventory > Operations > Deliveries and create a new delivery. - Add details > mark as Todo > Validate > Generate Delivery Guide. **Error:** `AttributeError: 'stock.move.line' object has no attribute 'qty_done'` **Root Cause:** At [1], the code references `line.qty_done`, but this field is defined in the `stock_barcode` module at [2]. When the Barcode Scanner is `disabled`, the field is not available, leading to the `error`. **Fix:** This commit updates the delivery guide values to use `line.quantity` instead of `line.qty_done` at [1] and at [4]. Since in the `stock_barcode` module at [3], `qty_done` is derived from `quantity`. [1]: https://github.com/odoo/enterprise/blob/ba5b9790f28e2f7eabda22e5992737eab0e82c6e/l10n_ec_edi_stock/models/stock_picking.py#L354 [2]: https://github.com/odoo/enterprise/blob/8c53e50df1cf9dc6d3ca4cae19c39135ac85d4e4/stock_barcode/models/stock_move_line.py#L23 [3]: https://github.com/odoo/enterprise/blob/8c53e50df1cf9dc6d3ca4cae19c39135ac85d4e4/stock_barcode/models/stock_move_line.py#L48-L50 [4]: https://github.com/odoo/enterprise/blob/8b72fdef63f634ccf436b49adbac5c1f9358c127/l10n_ec_edi_stock/views/report_delivery_guide.xml#L165 sentry-6851008674 Forward-Port-Of: odoo/enterprise#93775
This fixes an issue where changing only stock lot or location details on a manufacturing component could incorrectly mark it as consumed. Manufacturing orders now show component consumption only when the consumed quantity actually changes, reducing user confusion and keeping production records accurate.
Original PR description
Issue Before This Commit: ============================ When only the quants/move line were changed without modifying the quantity, the system automatically marked components as consumed (manual…
Issue Before This Commit: ============================ When only the quants/move line were changed without modifying the quantity, the system automatically marked components as consumed (manual consumption and picked boolean were set). This created confusion for the user since no actual consumption took place. Steps to Reproduce: ============================ - Install the `mrp` module. - Create a tracked product (lot/serial) with quants. - Create and confirm an MO having that product as a component. - Change only the quants (e.g., location of the quant, not quantity); notice that manual consumption and picked boolean are set. Cause of the Issue: =========================== This issue occurs when clicking the 'Details' button (`action_show_details` method) on a stock move. That action passes the context `force_manual_consumption`, based on that which directly sets the `manual_consumption` and `picked` booleans in the `write` and `create` methods. [see](https://github.com/odoo/odoo/blob/master/addons/mrp/models/stock_move.py#L276). With This Commit: ============================ Manual consumption and picked boolean are no longer set when only quants (not quantity) are changed. Component consumption is now triggered only if the quantity differs from the demand, ensuring consistency and avoiding confusion for the user. This fix avoids unintended behaviour by ensuring that the picked and manual consumption booleans change only when the quantity differs from the demand. TaskID:- 5062365 Forward-Port-Of: odoo/odoo#225386
Mobile users now see the template name as the main information when browsing signing templates, instead of seeing the creation date first. This makes it easier to choose the correct template and keeps the mobile view aligned with the desktop experience.
Original PR description
### Issue: - In mobile view, the template list was showing the creation date instead of the template name. - This made it hard to know which template you were selecting. --- ### Fix: - Changed the mobile view to show the template name as the main info. - The creation date is still shown, but as extra information. --- ### Impact: - Easier to find the right template on mobile. - Mobile and desktop views now look consistent. --- Task: 5038933 Forward-Port-Of: odoo/enterprise#93072
Guest shoppers could encounter a Forbidden error when the shop determined taxes or pricing rules from their location. The fix ensures the required fiscal setup can be read safely, keeping the online store accessible to anonymous visitors.
Original PR description
Ensure the fiscal position is always computed using sudo. When computing the fiscal position based on geolocated country, the result may not be return without sudo. Steps to reproduce: - Set a default Fiscal Position on the contact model (property_account_position_id) - Visit the website shop without logging in. - You will get a Forbidden error because Odoo raises an access error when fetching the fiscal position. This fix add a sudo() to the partner used to compute the fiscal position, so that when accessing the partner property, it will be returned with `env.su = True`. opw-5058588 Forward-Port-Of: odoo/odoo#225481
Mexican electronic invoice PDFs now use the same customer fiscal regime as the official XML file. This prevents mismatches between the human-readable invoice and the legally submitted CFDI document, reducing confusion for users and customers.
Original PR description
In l10n_mx: - Create a child contact under a company contact. - Set the fiscal regime of the child contact to one different from the company’s fiscal regime. - Create an invoice with the child contact and send it to the CFDI. In the XML, the fiscal regime used is the company’s, whereas in the PDF it is the child contact’s. This commit applies the same logic from _add_customer_cfdi_values to the PDF generation. After this change, the fiscal regime shown in the PDF will be the company’s, consistent with the XML. opw-4989605 Forward-Port-Of: odoo/enterprise#94259 Forward-Port-Of: odoo/enterprise#92482
Users can now open the duplicate transactions wizard even when no bank journal is linked. This avoids an unexpected error in Accounting and makes the view safer to access directly.
Original PR description
Currently, an error occurs when users try to open the view directly. Steps to reproduce: --- - Install `Accounting` module - Using Open View, Open `account.duplicate.transaction.wizard` view Traceback: --- `ValueError: Expected singleton: account.journal()` This error occurs because no account journal is linked to the wizard at [1], resulting in an empty `account.journal`. [1]- https://github.com/odoo/enterprise/blob/08564f3312c255f2f3ab95cef5a9bfc57727bd1f/account_online_synchronization/wizard/account_journal_duplicate_transactions.py#L32 sentry-6812500330 Forward-Port-Of: odoo/enterprise#94538
The portal signature form now checks whether a pop-up window is present before trying to use it. This prevents errors when the form is embedded directly on a page, making customer signature flows more reliable.
Original PR description
Description of the issue/feature this PR addresses: Be able to use the portal signature form outside of a modal. Current behavior before PR: If the signature form (```<t t-call=“portal.signature_form”>```) is used outside of a modal, an error occurs: ```TypeError: Cannot read properties of null (reading 'addEventListener')``` Desired behavior after PR is merged: The signature form can be used outside of a modal. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#224564
When users create a new partner during bank reconciliation, the system now chooses the receivable or payable action based on the transaction amount instead of missing customer or supplier history. This prevents the wrong payment button from appearing for brand-new partners, reducing confusion during reconciliation.
Original PR description
When creating a new partner from the set partner button, the partner doesn't have any rank (supplier or customer), this lead to have the payable button to be displayed since the condition to have it is to have a partner and not (customer_rank > supplier_rank). Since supplier rank and customer rank are 0 it will be False which lead to the button to be displayed. no task id Forward-Port-Of: odoo/enterprise#90435
Website sitemaps now avoid listing the same page more than once when website controllers are customized. This helps search engines receive cleaner sitemap data without changing which pages are available on the site.
Original PR description
When extending controllers (e.g. `WebsiteSale.shop`), sitemap entries were duplicated because deduplication relied on the endpoint function object. Overridden methods result in different function objects but identical sitemap URLs, leading to duplicates. This commit fixes the issue by deduplicating on the generated sitemap location (`loc['loc']`) instead of the function object, ensuring unique URLs in the sitemap even when controllers are extended. Fixes #224193 Forward-Port-Of: odoo/odoo#226810 Forward-Port-Of: odoo/odoo#224406
This fixes an access error that blocked branch or child companies from confirming sales orders when using loyalty programs defined by their parent company. The change lets the necessary loyalty history be recorded correctly, so shared loyalty programs work smoothly across company structures.
Original PR description
If you have a company parent with loyaltly programs and you try to confirm a sale order from a child company, an access error will be raised. Steps to reproduce: ------------------- * Create a…
If you have a company parent with loyaltly programs and you try to confirm a sale order from a child company, an access error will be raised. Steps to reproduce: ------------------- * Create a loyalty cards program * Set company to the current company * Create a branch company for the current one * Switch to branch company * Create a sale order, no need to add products, just a partner * Try to confirm the order > Observation: Access Error: > Sorry, Mitchell Admin (id=2) doesn't have 'create' access to: > -History for Loyalty cards and Ewallets (loyalty.history) Why the fix: ------------ Here's where the access error is being triggered: https://github.com/odoo/odoo/blob/35ea3dcb2eeb379c8b1127f0c7b42191853c0bd2/addons/sale_loyalty/models/sale_order.py#L106 Branches currently have access to the discounts & loyalty programs from the parent company, we extend the access to include loyalty history. Another solution could be to create the loyalty history using sudo() if the coupon's program id is a parent of the current company. opw-5055999 Forward-Port-Of: odoo/odoo#226226
The website SEO dialog now clears old image status changes when it is opened. This prevents image alt descriptions added in the editor from being accidentally erased when users reopen and save the SEO dialog without making changes.
Original PR description
Steps to reproduce: 1. Open Optimize SEO. 2. Mark an image as decorative. 3. Save it. 3. Give a description(ALT) to that image from editor. 4. Open Optimize SEO again and save without doing anything. Issue: The description(ALT) on the image being set is lost. Cause: When reopening the **Optimize SEO** dialog, `seoContext.updatedAlts` still contained entries from previous edits. As a result, saving without making any change triggered an call to `update_alt_images` which reset the `alt` attribute to empty, eventually discarding the description. This PR ensures `seoContext.updatedAlts` is reset when opening the dialog. Forward-Port-Of: odoo/odoo#226913
Odoo Studio now requires users to choose a related record type when creating AI-powered Many2one or Tags fields. This prevents crashes caused by incomplete field setup and gives users a clear visual warning before they confirm.
Original PR description
When adding an AI field of type Many2one or Tags, the Relation field was optional. If left empty, it caused a crash. This commit enforces that a Relation must be selected before confirming the dialog: - Add a red highlight if Relation is missing - Prevent field creation by returning early Task-5055796 Forward-Port-Of: odoo/enterprise#93873
This fix prevents Razorpay OAuth webhook setup from failing when website payments are enabled. It ensures payment connection URLs are built consistently, avoiding authentication errors caused by malformed addresses.
Original PR description
A bad URL could be generated when the `website_payment` module is installed, as it overrides `get_base_url` and may return a URL ending with `/`. Using f-strings to create URLs could result in a double slash `//`, causing errors. Steps to reproduce: - Install `website_payment` and `payment_razorpay_oauth` - Go to Payment Acquirers and connect via OAuth - Click "Generate your webhook" - "Authentication failed" error appears This fix uses `url_join`, like other payment providers, to build URLs correctly and avoid the double slash issue. opw-5079295 Forward-Port-Of: odoo/odoo#226639 Forward-Port-Of: odoo/odoo#226248
FedEx Home Delivery shipments can now generate return labels without triggering a recipient address error. This ensures affected US deliveries proceed smoothly when return labels are enabled.
Original PR description
**PROBLEM** When selecting FedEx Home Delivery service, and enabling the return label generation, we got the error `RECIPIENT.ADDRESS.ERROR`. **STEPS TO REPRODUCE** 1. Install delivery_fedex_rest (use the new fedex credentials). 2. On the FedEx US shipment method (demo data) select FedEx home delivery service, and check the `Generate Return Label` option. 3. Create a SO, add shipping with FedEx US, validate the SO. 4. Validate the delivery order, and notice the FedEx API return an error. **CAUSE** For Home Delivery Service, the recipient address need to have the `residential` flag set to true. In `_return_package()`, the request sent doesn't include this flag, leading to an error. **FIX** Fix `_return_package()` query to include the `residential` flag. opw-4939065 Forward-Port-Of: odoo/enterprise#94463
The printer interface now handles printer setup errors more gracefully. If a printer cannot be added due to system restrictions or an invalid name, the issue is logged and the interface keeps running instead of stopping.
Original PR description
Before this commit, if CUPS raised an error when adding a printer in the `supported()` method of the printer driver, the exception would not be caught causing the printer interface to stop. This can happen for example if the filesystem is read-only or the printer has an invalid name. After this commit, we catch any CUPS errors and log them, allowing the printer interface to continue running. We also enter write mode before adding the printer to prevent any read-only errors. task-5086036 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227121
Users can now open activities from the "View all activities" menu even when they do not have access to the related record. This prevents an error and still lets them complete the activity using the appropriate activity form.
Original PR description
**Steps to reproduce** 1. Create an activity on a record and assign it to a user who doesn't have access to this record. (e.g. create an activity on a `hr.employee` record and assign to a user without HR rights). 2. With this user lacking access rights, click on "View all activities" in the systray. 3. Click on the activity: error **Cause** The user may not have access rights to the record related to an activity. **Change** Open the activity's form view, we use `mail_activity_view_form_without_record_access` to display the "Mark as done" button. opw-4925744 Forward-Port-Of: odoo/odoo#226950 Forward-Port-Of: odoo/odoo#222649
Fixes planning date calculations so security lead time is applied only once when products move through multiple warehouses. It also ensures manufacturing security lead time is included even when a product has no bill of materials, improving delivery and production schedule accuracy.
Original PR description
In this bug, when there are multiple warehouse, and a warehouse is supplied by another one, the security lead time is repeated in calculations. To reproduce the bug: 1- Create a db with, stock, mrp,…
In this bug, when there are multiple warehouse, and a warehouse is supplied by another one, the security lead time is repeated in calculations. To reproduce the bug: 1- Create a db with, stock, mrp, sale installed. 2- Unarchive `MTO` route. 3- Set `Security Lead` Time in Setting. 4- Create two warehouses wh1, wh2. 5- In wh1, set `Manufacture to Resupply` to True. 6- In wh2, set `Manufacture to Resupply` to False and make it resupply from wh1. 7- Create a product and track inventory. 8- Create a BOM for the product. 9- Enable `Manufacture`, `MTO`, `wh2: Supply Product from wh1` routes for the product. 10- Create a new Quote for the product and in the Delivery, select `wh2` as the warehouse. Confirm the Quote. 11- Open MO. Security lead time is considered twice in dates calculations which is mistake. To solve this issue, we must call `_get_dates_info` only once. The current condition might be True more than once for multiple moves. We should also check that it is not True for next moves which otherwise means the security lead time is already effected. This issue is reproduced because this condition is not sufficient to ensure it is called once: https://github.com/odoo/odoo/blob/c0a7b51c9e14d29cefa96c29dd716b7aec698818/addons/stock/models/stock_move.py#L1656-L1657 The above condition is written to ensure we are adding the delay only when move location is warehouse stock location. This cause problem in multi-warehouse because we have this case that move location is warehouse stock location once for wh1 and once in wh2. To solve this issue, we make sure the call `_get_dates_info` doesn't affect when the move has rules with src location in warehouse stock location. related: #112325 opw-4889642 Forward-Port-Of: odoo/odoo#226712 Forward-Port-Of: odoo/odoo#224232
This fix prevents a demo data installation error when Italian Riba and Stripe expense features are used together. It ensures the sample company bank setup can handle the extra bank journal created by Stripe expenses, so demo environments install reliably.
Original PR description
Steps: 1. Install `hr_expense_stripe` and activate demo data 2. Install `l10n_it_riba` 3. `l10n_it_riba` demo data install fails with an error Since [this commit](https://github.com/odoo/enterprise/commit/752ffcbcd0c33e2886aa7bcec469e16d3704d7a9), an additional bank journal is created on every company by `hr_expense_stripe`, and `l10n_it_riba` demo data only expects one. task-none
Fixed an issue in Odoo Sign where completed signature emails could include multiple attachments with duplicate names and an extra .pdf extension. Recipients now receive clearly named signed documents, reducing confusion when downloading or filing multiple completed documents.
Original PR description
Steps to reproduce: 1. Install Sign. 2. Configure an outgoing email server. 3. Send a sign request for 2 or more documents to the admin (use your own email) 4. Open the email, sign and validate the documents. 5. You will receive an email. **Issue:** - You observe there are attachments in the email with same name and an extra `.pdf` as file extensions (e.g. `abc.pdf.pdf`). **Cause**: https://github.com/odoo/enterprise/blob/a1cd174c65fa181701cc3c5883fb5ab43b2803d8/sign/models/sign_request.py#L588-L594 - The code used `record` instead of the current `document` to determine the attachment name, causing the wrong generated name. **Solution:** - Use the `document` name when generating the attachment filename. opw-4965405 Forward-Port-Of: odoo/enterprise#92183
Product pages now make it easier for shoppers to see which image is currently selected in the image carousel. The active thumbnail has a stronger highlight, while inactive thumbnails are dimmed unless hovered, reducing confusion when browsing product photos.
Original PR description
Steps ----- 1. Have a published product with multiple images; 2. go to its website page; 3. open website editor; 4. set Images Ratio to Wide; 5. enable pop-up on click; 6. save; 7. browse through the images. Issue ----- - While there is a border around the active thumbnail in the bottom row, it is barely visible, making it difficult to see which image is currently being shown. Cause ----- - The border is only 1 pixel wide. Solution -------- - Increase the width of the border to 4 pixels, change the color to `$primary`, and hide the border for inactive images. - Set opacity of thumbnails that aren't selected or hovered over to 0.5. opw-4908881 Forward-Port-Of: odoo/odoo#224644
Refreshing the Point of Sale while the screensaver is active now returns users to the first POS screen instead of reopening the screensaver. This prevents cashiers from getting trapped on an unresponsive screensaver and needing to close and reopen the tab.
Original PR description
Fix issue appearing when you reload the page while the ScreenSaver is active, which caused the ScreenSaver to be displayed again after the reload (and the user is stuck on that screen). Steps to reproduce: - Open POS - Trigger screen ScreenSaver - Reload the page (F5) (without triggering any user activity so we stay on the screen saver) - The ScreenSaver is displayed again after the reload - => The user is stuck on the saver, moving clicking or typing does not do anything, you have to close the tab and open it again => Now when refreshing the page while on the screen saver, we just directly navigate to the first page of the POS. Description of the issue/feature this PR addresses: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Sales and purchase order sections are no longer imported as regular order lines when a PDF is dropped into the Purchase app. This prevents incorrect quantities, prices, and misleading import warnings, improving accuracy for electronic order processing.
Original PR description
Steps to reproduce:
- Create Sales/Purchase order with sections
- Print Sales/Purchase order as PDF
- Drop the PDF into purchase app
Problem:
- Sections are added as a normal order line with quantity, price, etc..
- `return True` was removed from `_import_order_ubl` because it
shows an incorrect warning in the chat log.
"Attachment {{name}}.xml not imported: True" whenever the attachment
is imported correctly and its supposed to show the reason if something
goes wrong not "True".
**Notes:**
- Orders were filtered to not include sections, because
UBL does NOT support sections.
- `return True` was removed from `_import_order_ubl` because it
shows an incorrect warning in the chat log.
"Attachment {{name}}.xml not imported: True" whenever the attachment
is imported correctly and its supposed to show the reason if something
goes wrong not "True".
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fixes a race condition in Mail tests where message content and attachment updates could arrive in the wrong order, causing inconsistent test results. The change makes the test flow wait for messages and update attachments through the user interface, improving reliability without changing business functionality.
Original PR description
Before this commit, the test could experience a race condition where the load of the message and the update of the content of that message happen at the same time, if that happens and the update of the content is received by bus before the load of the message (which therefore does not contain any attachment), then the store was overriding the attachment. This commit should solve the problem in the test by waiting for the messages at the beginning of the test as well as updating the attachments in the ui and not by rpc directly. The race conditions should be fixed globally and are not only linked to this issue. fixes-runbot-66304 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226922
Customers who paid an invoice or order can now update their billing address when no country was previously set. This prevents checkout and portal address forms from blocking a required country update, reducing payment and billing friction.
Original PR description
After paying an invoice or sale order, a customer without a billing country cannot update the country in their billing address because the form is disabled by the portal's country edition rule. **Steps to reproduce:** 1. Create a customer without a billing country. 2. Generate an invoice or sale order for that customer. 3. Pay the invoice/order (possible with some payment providers). 4. Go to the customer portal and try to update the billing address. The country field is disabled, preventing the customer from setting their country. This fix ensures that if the partner has no country set, the field remains editable even when normal country edition restrictions apply. This issue also affects the `website_sale` module, specifically the checkout process, where the country field may be blocked if not handled properly.
This update fixes an internal automated test that could occasionally fail because a randomly generated database identifier happened to contain a specific test value. It narrows the check to the relevant AI prompt and conversation data, improving test reliability without changing user-facing behavior.
Original PR description
The database_id is an uuid. It can happen that it contains the substring "1337". The test only needs to check if the value is not in the "prompt" or "conversation_history" keys. Thus we can remove the "database_id" key runbot-198561 Forward-Port-Of: odoo/enterprise#94807
The appointment booking page now shows the correct number of people allowed based on the available or selected resource. This prevents customers from seeing an artificially low capacity and helps businesses accept bookings up to the true resource limit.
Original PR description
**How to reproduce:** - Create an appointment with availability assigned to a resource. - Enable 'Manage Capacity' - Set the capacity of the first resource lower than the second one. - Open the appointment's booking page. **Technical Reason:** If appointment is scheduled based on 'resource_time' then resource_default is updated as the first value of resource_possible. Related PR: https://github.com/odoo/enterprise/pull/47059 **After this PR:** 'Number of people' dropdown will display the maximum capacity from all available resources. Task-4664393 Forward-Port-Of: odoo/enterprise#94832 Forward-Port-Of: odoo/enterprise#84243
This fixes issues in the salary package and Belgian salary configurator flows that could cause automated employee or applicant journeys to fail. It ensures Belgium-specific questions are only used when the Belgian module is installed and improves handling of signed salary offers, reducing errors during hiring and contract setup.
Original PR description
`l10n_be_hr_contract_salary` adds a bunch of fields to the salary configurator (by way of new hr.contract.salary.personal.info records). These fields can not be filled in `hr_contract_salary` as they are not present there, thus if the employee flow tour is run with just `hr_contract_salary` installed it fails as soon as it tries to fill one of these additional fields. Move the filling of the fields to `l10n_be_hr_contract_salary` extending the base tour (technically it might be possible to move just the lang and remove the rest since that's the only required field). https://runbot.odoo.com/odoo/error/232583
This fix prevents tax report external values from being changed once the relevant tax return period is locked. It also adjusts the tax closing process so required default values are created before the lock is applied, helping preserve submitted tax data while avoiding closing-flow errors.
Original PR description
[FIX] account_reports: external value check lock date This commit add the check that protects external values from being edited out of the lock date. For example when the tax report is submitted, the…
[FIX] account_reports: external value check lock date This commit add the check that protects external values from being edited out of the lock date. For example when the tax report is submitted, the user is not supposed to modify any external values anymore. To do this, we had to modify the tax closing flow a little bit: when closing the tax period, we now generate the default external values before setting the tax lock date. This is because the generation of the default external values was done for the period we were closing, but now that we forbid the creation of an external value after the lock date we had to change the order of the flow. Due to one specific corner case (l10n_fr), we had to keep a hack to bypass the Tax Return Lock Date check. This was done with a context key and will have to be removed in master. The case is the following : when the user generates the tax closing entry, the external values for the period are generated and the Tax Return Lock Date is set with the last day of the month. Then if the user tries to submit the EDI VAT report, it tries to create 2 external values for the carryover but as the lock date was set, it raises an error. task-5012442 Forward-Port-Of: odoo/enterprise#94641 Forward-Port-Of: odoo/enterprise#92949
When a TicketBAI submission fails for a Spanish POS order, the receipt will no longer print an invalid QR code. This avoids confusing customers and helps ensure receipts only include QR codes when the tax reporting submission has been accepted.
Original PR description
Currently if the TicketBAI upload fails, a QR code is printed with the value `true`. Steps to reproduce ----- 1. Validate a POS order 2. Have a request exception occur during the TicketBAI post 3. Receipt is printed with an incorrect QR code Issue ----- `get_l10n_es_pos_tbai_qrurl()` returns None if the edi document is not accepted. This is then interpreted as `true` by the client and a QR code is printed. Solution ----- Explicitly return an empty string if the edi document is not accepted. Forward-Port-Of: odoo/odoo#227293
This fix prevents unnecessary overtime recalculations while editing attendance records. It ensures manually validated overtime hours are preserved and updated correctly when users change checkout times, avoiding confusing save behavior.
Original PR description
This fixes a weird behaviour where field that is not triggering the compute on the save because it was already triggered on the onchange If a user ser the validated_overtime_hours to a value that is…
This fixes a weird behaviour where field that is not triggering the compute on the save because it was already triggered on the onchange If a user ser the validated_overtime_hours to a value that is not the one in overtime_hours, upon changing the check_out time we will trigger the compute for both those fields. Overtime_hours calculates it's value based on attendance.overtime model, which is not being updated here, hence it will have the same value. Validate_overtime_hours in the other hand will be updated since there is a write in overtime_hours (even though with the same value) and this will mark the field to be updated when a web_save happens. Now when the save happens the overtime_hours is updated but even though validate_overtime_hours depends on it, it won't be updated since it's being writen to, as a field to be updated This fix aims to prevent writing to overtime_hours when there is no real need to, preventing the described issue opw-4806193 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222832
UK and New Zealand tax return reports now respect each company's configured fiscal year dates. This prevents invoices from being included or excluded in the wrong quarter when the fiscal year does not end on December 31.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_uk_reports - Switch to a British company (e.g. UK Company) - In Accounting settings, set the last day of the fiscal year to another date than "December 31" (e.g. "January 31") - Create some invoices with tax between the 1st of January and the 30th of April - Go to "Accounting / Accounting / Closing / Tax Returns" - Open the "Tax Report (GB)" for the first quarter (i.e. Tax Q1) **Issue: (same issue for NZ localization)** The Tax Report is ignoring the configured date of the fiscal year. All the invoices from January are included and those from April are excluded. It should be the opposite. **Solution:** Override the "_get_start_date_elements" method for the British tax report that allows to define the start date. opw-4939971 opw-5067877 Forward-Port-Of: odoo/enterprise#94793
Fixed an issue where editing product properties could show an empty notification when the product had no category. Users now see the intended warning message, reducing confusion during product setup.
Original PR description
Versions -------- - saas-18.3+ Steps ----- 1. Create a new product without a category; 2. try to edit properties. Issue ----- An empty notification appears. Cause ----- The `_getPropertyEditWarning` override in `account_asset` introduced by PR odoo/enterprise#87807 doesn't return the value of the `super` call. This was introduced in a forward port as the logic to display the warning was changed in `web` in saas-18.3, and not requiring a return value in previous versions. Solution -------- Return the `super` call. opw-4980006 Forward-Port-Of: odoo/enterprise#94583
This update prevents an error in the Mail app when empty values are included while looking up email records. It improves reliability by safely ignoring invalid empty entries before processing them.
Original PR description
Browse breaks when given a bool, so the solution is to filter the list from false values before browsing --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#225916
This change removes a broken upgrade step that could stop some databases from moving from version 18.3 to 18.4 or later when salary contract features were installed. The related data update is handled earlier in the correct HR upgrade process, helping upgrades complete reliably.
Original PR description
The `hr_contract` table is renamed to `hr_version` as part of the https://github.com/odoo/upgrade/blob/3bea30d1fd0cd202006da4ad11e00e283cbc78d0/migrations/hr/saas~18.4.1.1/pre-migrate.py#L29, script,…
The `hr_contract` table is renamed to `hr_version` as part of the https://github.com/odoo/upgrade/blob/3bea30d1fd0cd202006da4ad11e00e283cbc78d0/migrations/hr/saas~18.4.1.1/pre-migrate.py#L29, script, which is executed before any `hr_contract_salary` script, including module ones. As a result, any database from 18.3 to 18.4+ with `hr_contract_salary` < 2.1 will run into:
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/saas-18.4/odoo/service/server.py", line 1410, in preload_registries
registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'])
File "<decorator-gen-6>", line 2, in new
File "/home/odoo/src/odoo/saas-18.4/odoo/tools/func.py", line 89, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/saas-18.4/odoo/orm/registry.py", line 175, in new
load_modules(
File "/home/odoo/src/odoo/saas-18.4/odoo/modules/loading.py", line 455, in load_modules
load_module_graph(
File "/home/odoo/src/odoo/saas-18.4/odoo/modules/loading.py", line 181, in load_module_graph
migrations.migrate_module(package, 'pre')
File "/home/odoo/src/odoo/saas-18.4/odoo/modules/migration.py", line 220, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/saas-18.4/odoo/modules/migration.py", line 257, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/enterprise/saas-18.4/hr_contract_salary/upgrades/saas~18.3.2.1/pre-unarchive-partially-signed-offers.py", line 4, in migrate
cr.execute(
File "/home/odoo/src/odoo/saas-18.4/odoo/sql_db.py", line 426, in execute
self._obj.execute(query, params)
psycopg2.errors.UndefinedTable: relation "hr_contract" does not exist
LINE 4: FROM hr_contract c
^
```
As a fix, the query is moved into the `hr` script mentioned above.
see: https://github.com/odoo/upgrade/pull/8466
opw-5071923
upg-3121357
tbg-2136Italian split payment taxes now show the correct label in the Taxes column on PDF documents instead of appearing like standard taxes. This helps businesses produce clearer, more accurate tax documents for customers and compliance review.
Original PR description
Split payment taxes were not labelled correctly in the PDF's "Taxes" column, they were labelled as standard taxes. <img width="1214" height="598" alt="image" src="https://github.com/user-attachments/assets/f1ea57bd-9a7f-460f-8c81-6a89585ba6d8" /> Forward-Port-Of: odoo/odoo#227284 Forward-Port-Of: odoo/odoo#226366
Renamed spreadsheets now keep their updated name when users create another spreadsheet and navigate back through the breadcrumb. This prevents confusion from previously renamed spreadsheets appearing as untitled.
Original PR description
Steps to reproduce: - Create a spreadsheet - Rename it to "My awesome spreadsheet" - Click on File -> New - Go back to "My awesome spreadsheet" from the breadcrumb => The spreadsheet is untitled. This was caused by the fact that the name was not saved in the local state of the action. Task: 4942117 Forward-Port-Of: odoo/enterprise#93163
Features or functions removed from Odoo
An outdated automated website editing test was removed because it had been disabled for months and no longer matched the current editor behavior. This reduces false failures in the testing pipeline without changing the experience for end users.
Original PR description
Test has been disabled in 18.0~master since March, it's even more broken in 19.0+ following #225791 (migrated to a `setSelection` with a different protocol, but the tour was not updated to the new protocol). https://runbot.odoo.com/odoo/error/116797 Forward-Port-Of: odoo/odoo#227288 Forward-Port-Of: odoo/odoo#227163
Documentation and clarification updates
This pull request updates Quartile's corporate contributor license agreement documentation. It keeps Odoo's legal contributor records current, supporting compliant contribution management without affecting product functionality.
Original PR description
@qrtl --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#226204
This pull request records a contributor license agreement signature from tsezgin. It supports Odoo's legal contribution process and does not change product functionality or user workflows.
Original PR description
The commit contains my CLA signature Forward-Port-Of: odoo/odoo#226307