Tuesday, November 18, 2025
53 changes · 19.0
Enhancements to existing features
This change adds a debug-only action to retry payment post-processing directly from the transaction screen. It helps teams quickly see why a payment was not fully completed, reducing the risk of missed subscription updates or repeated payment attempts.
Original PR description
Before this commit: If there was any transaction that was not post-processed, we couldn’t see what was wrong. After this commit: Now we have button in debug mode only for post-processing so we can see error on UI and find exact cause of issue in logger. Reason: If a payment is not post-processed, it can cause major issues. For example, a subscription may not detect that the payment was completed, so the next invoice date is not updated. As a result, the system may attempt to charge the customer again the next day using the token, even though the payment was already completed. This repeats until the post-processing step is successfully executed or someone manually creates the invoice. To fix this, we need to know what the problem is without having to dig through large logs (which regular users, especially on SaaS, often don’t have access to). task-4936432
Users can now drag and drop an attachment directly onto a new expense form without being blocked by missing required fields. The duplicate attachment link in the expense list view was also removed, making the interface less confusing.
Original PR description
[IMP] hr_expense: enable attachment drop on expense form view Steps to reproduce the use case that is improved: - create a new expense (without writing anything) - drag and drop an attachment -> Some required field prevent this behavior Solution: Pre-fill values that are required when dropping an attachment. ---------------------------------------------------------------------------------------------- [FIX] hr_expense: remove duplicate attachment link remove an unnecessary link to the attachments of expenses in the list view. task-4684825 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update adds missing tax entries for the Philippine localization and cleans up tax descriptions by removing unnecessary ATC codes. It helps ensure local tax data is more complete and easier to read in reports and forms.
Original PR description
Spec: Several taxes were missing in the Philippine localization. Existing tax descriptions were filled with unnecessary codes. IMP: Added additional taxes as per the provided specifications. Updated descriptions for existing taxes by excluding ATC code. Related PR: https://github.com/odoo/enterprise/pull/99354 TaskID-5248240
The Saudi payroll rules for end-of-service benefits were updated to better match legal requirements. The calculation now uses actual days and service duration more accurately, and retirement is treated like contract ending rather than resignation, which helps produce more accurate payouts and provisions on payslips.
Original PR description
- adjusted the calculation of end of service benefit to use actual number of days and changed the calculations to use total years instead of total days to be compatible with how it's stated by the law - changed the case of retirement to be handled the same as the case of contract ending and not resignation - changed the way eos provision is calculated on the payslip to account for the duration of employment of the employee - added test for eos benefit calculation which checks the cases of resignation and end of contract - changed the string and tooltip of `l10n_sa_number_of_days` to be more descriptive of what it does task-id: 4766060
This change makes it easier to determine which warehouse name is sent to SendCloud when preparing shipments. It gives businesses more flexibility to match the correct sender address, especially when the warehouse naming rules are not a simple one-to-one match.
Original PR description
As choosing the proper sender address in SendCloud can be more complex than matching a name to a fixed name in Odoo we open up the freedom to inherit the retrieval of the warehouse name. Info: @wt-io-it Forward-Port-Of: odoo/enterprise#97595
Resolved issues and error corrections
DATEV exports now work correctly even when a German company name contains a dot. This prevents the export from failing with an error and ensures accountants can generate the report without interruption.
Original PR description
Currently companies with a dot ('.') in the name cannot export the DATEV report due to a traceback.
Steps to reproduce:
- Select a German (DE) Company having a dot in the name.
- Open Accounting / Reporting / Ledgers / General Ledger
- Click cog > Datev DATA (zip)
Issue:
A Traceback will occur
`Error "ValueError: too many values to unpack (expected 2)"`
This occurs because the system separate the filename from the extension without halting to the first `.`, leading to the error.
opw-5232073This change ensures certain report attachments that start from a remote source are converted into local files before being used. This helps reports that rely on attached images or chatter content work correctly and reliably, especially with cloud storage setups.
Original PR description
During commit #226094, several methods were added to allow fetching remote resources for certain reports. After that commit, we notice that some attachments (like images -> image_src) must need the file localy. To avoid this issue we decided to convert this documents from remote to localy (binary), to be able to manage them. It'll just happen for the reports that need to add attachments from the chatter. OPW-5036638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235710 Forward-Port-Of: odoo/odoo#235077
This change makes the web client check browser capabilities before using a browser-specific setting, instead of assuming it is always available. It helps prevent errors on browsers that hide this information, improving reliability for users on affected devices.
Original PR description
This commit uses "Feature detection" to avoid some error when the platform key is not available from navigator. > The platform property indicates the platform/OS the browser is running on. > Theoretically this information is useful for detecting the browser and serving code to work around browser-specific bugs or lack of feature support. However, this is unreliable and is not recommended for the reasons given in User-Agent reduction and Browser detection using the user agent. > Feature detection is a much more reliable strategy. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Testing/Feature_detection task-4420689 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235958
This fix ensures the QRIS API key and merchant ID fields are shown in the bank account form. The fields were being placed in a hidden part of the page, so users could not see or fill them in.
Original PR description
**Description of the issue/feature this PR addresses:** This issue occurs because the XPath targeting the `currency_id` field is placed inside a `<div>` that becomes invisible under certain conditions. The `view_partner_bank_form_inherit_hr` view is loaded first due to its sequence, and the `l10n_id` view is applied afterward, causing the QRIS fields to be inserted into that hidden `<div>` from `view_partner_bank_form_inherit_hr`. **Current behavior before PR:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are not visible. **Desired behavior after PR is merged:** The fields l10n_id_qris_api_key and l10n_id_qris_mid are visible by changing XPath target Task: [5247678](https://www.odoo.com/odoo/project.task/5247678) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235949
This change stops portal users from interacting with the chatter on a task before it has been saved. It prevents a crash when someone tries to mention a user in a new task, improving stability when working in shared projects.
Original PR description
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module.…
Currently, an error occurs when a portal user opens a `shared project` and tries to `mention(@)` someone in the chatter of a `new(unsaved) task`. **Steps to produce:** - Install the `project` module. - Open the project app and create a new project with at least one task. - From the project’s `dropdown menu(⋮)`, select `Share Project`. - Add a `collaborator: Joel Willis`, with `Edit access` mode, copy the public link, and click `Share Project`. - Open the shared link in an incognito window and sign in as a portal user. - Open the `project folder` > open any task > click `New` > type `'@'` in the chatter. **Error**: `ValueError: Expected singleton: project.task()` **Root cause:** The `composer(message box)` allows typing and mention suggestions even when the task record is not yet saved (`self.thread.id` is `undefined`). At [1], the method is called on an `empty` recordset, causing an `error`. **Fix:** This commit prevents users from writing in the chatter by stopping the composer initialization when the record(thread) is `unsaved`. [1]: https://github.com/odoo/odoo/blob/5cf96828652c2388808b3e49ae67e188c401ec63/addons/project/models/project_task.py#L2051-L2071 sentry-6982269693 Forward-Port-Of: odoo/odoo#235184
The employee org chart button now opens the Hierarchy view on mobile devices instead of defaulting to the Kanban view. This makes it easier for users to access the correct org chart display when viewing employees on the go.
Original PR description
Steps to Reproduce: - Open an employee record. - Set managers for the employee. - Open the employee’s form view on mobile. - Click org chart stat button. Before: - On mobile, the org chart button opened the Kanban view by default. After: - On mobile, the org chart button now opens the Hierarchy view by default. task-5245129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235228
This change prevents a crash that could happen when generating Belgian accounting reports during migration. It corrects how the fiscal year start date is calculated so it works properly even for dates like February 29 in non-leap years.
Original PR description
``` File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate generate_or_refresh_all_returns(company) File…
```
File "/tmp/tmpm_3a__2e/migrations/account_reports/saas~18.3.1.0/end-account-returns.py", line 340, in migrate
generate_or_refresh_all_returns(company)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 228, in _generate_or_refresh_all_returns
self._generate_all_returns(fiscal_country.code, company, domestic_tax_unit)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 24, in _generate_all_returns
super()._generate_all_returns(country_code, main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 281, in _generate_all_returns
report_type._try_create_returns_for_fiscal_year(main_company, tax_unit=tax_unit)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 353, in _try_create_returns_for_fiscal_year
period_date_from, period_date_to = self._get_period_boundaries(main_company, date_pointer)
File "/home/odoo/src/enterprise/19.0/account_reports/models/account_return.py", line 530, in _get_period_boundaries
start_day, start_month = self._get_start_date_elements(company_id)
File "/home/odoo/src/enterprise/19.0/l10n_be_reports/models/account_return.py", line 16, in _get_start_date_elements
fiscal_year_date = date(2025, int(main_company.fiscalyear_last_month), main_company.fiscalyear_last_day)
ValueError: day is out of range for month
```
```
(Pdb) main_company
res.company(3,)
(Pdb) main_company.fiscalyear_last_month
'2'
(Pdb) main_company.fiscalyear_last_day
29
(Pdb) date_from
datetime.date(2025, 3, 1)
```
- During the migration process the system calls [_generate_or_refresh_all_returns](https://github.com/odoo/upgrade/blob/e20a9e2edec4441b2c7aa5858db2a53fb2e9b215/migrations/account_reports/saas~18.3.1.0/end-account-returns.py#L340) which internally uses [_get_start_date_elements](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L14) to compute the fiscal year start date.
- The customer has configured fiscalyear_last_month = February and fiscalyear_last_day = 29 Because of this configuration, the method attempts to construct 29th February 2025, which is invalid since 2025 is not a leap year. The issue occurs because the method uses a hardcoded year [(2025)](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_be_reports/models/account_return.py#L16) instead of determining the year dynamically.
- I reviewed implementations in other localizations and found that this logic has [1](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_uk_reports/models/account_return.py#L33), [2](https://github.com/odoo/enterprise/blob/ebdc2fe2ade72b1505dac5490b7df2a1d06fcb4b/l10n_nz_reports/models/account_return.py#L8) already been corrected there to compute the appropriate start date dynamically.
- I’ve updated this localization to follow the improved implementation used in other countries, so the start-date calculation now works correctly in all cases, including leap years and any fiscal year settings the customer may configure.
opw-5249243
Forward-Port-Of: odoo/enterprise#99353This update fixes a problem on mobile websites where a hidden mega menu could still block taps on the page. As a result, users can reopen the menu normally after closing it, improving navigation reliability on phones and tablets.
Original PR description
Steps to reproduce: ==================== 1. Add a mega menu. 2. Add effects to the mega menu columns ex (Animation on appearance, Fade, direction from bottom) 3. Switch the website display to mobile view. 4. Click on the mega menu. 5. Go back and try to click again. → The mega menu cannot be opened again. Cause: ====== When the mega menu is hidden, its section remains in the DOM and still captures pointer events. As a result, clicks on the screen (including attempts to reopen the mega menu) are intercepted by the hidden element instead of reaching the intended target. Solution: ========= Disable pointer events on the mega menu section once it is hidden to ensure subsequent clicks behave correctly. opw-5129316 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233636
This change corrects the logic that decides when OSS return reports should be generated. As a result, OSS sales and import returns will only be created when their conditions are actually met, avoiding unnecessary or incorrect report generation.
Original PR description
The OSS Sales returns was generated even when its condition wasn't met since auto_generate was still at True. The OSS Imports didn't have any condition and has one which is similar to the OSS Sales.
This fix prevents the Inventory app from crashing when a stock quantity record is opened without a Location set. It improves stability for users editing quantities, especially when working with new or unsaved records.
Original PR description
Currently, an error is produced when accessing the stock quant form view without a location set. **Steps to Reproduce:** 1. Install the Inventory module. 2. Create a product with tracking enabled (By Unique Serial Number). 3. Click **"Update Quantity"** (opens list view). 4. Click **New**, click View on the unsaved record (opens form view). 5. Remove the Location field. **Error:** `TypeError - sequence item 0: expected str instance, bool found` **Cause:** In the display name computation at [1], the system attempts to join name parts where one of them can be `False` if the location is not set. **Fix:** Before generating the display name, it now checks whether the record is saved (record.ids). If the record is unsaved (no ID), it sets an empty `display_name` and skips the name-joining logic. [1] - https://github.com/odoo/odoo/blob/16e889bf5885c4d827b8c2c5dce102f98aad689f/addons/stock/models/stock_quant.py#L599 sentry-6717759358 Forward-Port-Of: odoo/odoo#234552
This fix ensures imported French FEC entries keep the right matching status so automatic reconciliation works correctly across different accounts. It prevents one reconciliation from unintentionally stopping later ones from being matched, improving import reliability and reducing manual cleanup.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit provides a test to reproduce this issue. opw-5086823 Forward-Port-Of: odoo/enterprise#98855
This update prevents accidental line breaks from being included in Swiss QR code fields. As a result, QR codes are less likely to be rejected by banks or payment systems due to incorrect formatting.
Original PR description
Swiss QR codes have required information for each line of the QR code. Newline characters present in a field's content shift the content to a different line than intended, causing the QR code to be rejected. This commit removes newline characters from the field elements and alters a unit test to check if this issue occurs again. opw-5095997 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233880
This fix ensures the restaurant floor plan only shows booking notifications for the correct appointment type set in the POS configuration. It also prevents misleading bookings from appearing and then disappearing after a refresh, making the booking experience more reliable for staff.
Original PR description
Task: [#5005216](https://www.odoo.com/odoo/my-tasks/5005216) Enterprise v17.0: [#93714](https://github.com/odoo/enterprise/pull/93714) --- **Before:** If no appointment type is specified in the POS config and a table is booked via the website, the floor plan is notified of a new booking because the resource used is one of the POS config resources. However, if the page is refreshed, the booking disappears since no appointment type is defined in the POS config **After:** The floor plan is notified of a new booking only if the appointment type of the booking matches the one specified in the POS config. If no appointment type is set in the POS config, no booking notifications are sent. Additionally, when the "Table Booking" field is unchecked in the POS config, the appointment type is automatically unset. Forward-Port-Of: odoo/enterprise#98887 Forward-Port-Of: odoo/enterprise#93636
Imported accounting entries that share the same matching number will now be handled more reliably during automatic reconciliation. This prevents one reconciliation from accidentally blocking others on different accounts, helping imported data get matched correctly without manual follow-up.
Original PR description
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the…
When a FEC file imports journal items, it will create them to draft with reconciliations stated by a matching number starting with "I" (also the case for other some types of imports). Once the entries are posted, the system will create odoo reconciliation records for those journal items. The issue lies in this part of the code removing the matching when performing reconciliations for the same matching number https://github.com/odoo/odoo/blob/9d34c7ee85d105a56c3393a3dbb3e5d62d4d634a/addons/account/models/account_partial_reconcile.py#L206 Most of the time it's not a problem for the auto reconcile mechanism of FEC. However since this mechanism reconciles grouped on matching + account, we can end up in a case where a first reconciliation on account A will remove all matching number similar but on account B leading to no automatic reconciliation for them. This commit aims to fix that by removing amls imported matching number (starting with "I") from the reconciled amls to consider. opw-5086823 Forward-Port-Of: odoo/odoo#234481
Bancontact payments that require an extra verification step are now kept in a pending state instead of being marked as failed. This prevents customers from seeing an error during the normal redirect-based payment flow and helps payments complete correctly.
Original PR description
When paying with Bancontact, in case a 3DS validation is required (challenge flow), Wordline will send a webhook (see below) to indicate that an external (asynchronous) validation was requested.…
When paying with Bancontact, in case a 3DS validation is required (challenge flow), Wordline will send a webhook (see below) to indicate that an external (asynchronous) validation was requested.
Example of recevied webhook:
```
{
'apiFullVersion': 'v1.1',
'apiVersion': 'v1',
...
'payment': {
'status': 'AUTHORIZATION_REQUESTED',
'statusOutput': {
'isAuthorized': False,
'isCancellable': False,
'isRefundable': False,
'statusCategory': 'PENDING_CONNECT_OR_3RD_PARTY',
'statusCode': 51
}
},
'type': 'payment.authorization_requested'
}
```
Since efc2788dfccd, when receiving such webhook we set the transaction as error then force the user flow to `redirect`; this was done to handle payment w/ token (`online_token`) where a 3DS challenge is still required.
But for Bancontact - which is non-tokenizable - we will always be in the "redirect" mode, so we must keep the transaction as `pending`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#235847We removed a restriction that prevented users from reusing or copying tax groups when the linked payable or receivable accounts did not match a specific account type. This makes tax group setup and maintenance more flexible while still allowing account types to be adjusted afterward.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Community PR:** https://github.com/odoo/odoo/pull/235548 opw-5231379 Forward-Port-Of: odoo/enterprise#99421
When a lead is moved to a different sales team, its stage is now refreshed to match that team’s available stages. This prevents leads from staying in an outdated stage that no longer fits the team they belong to, improving consistency for sales users.
Original PR description
**Steps to reproduce:** - Install CRM and set the Leads configuration setting - Go to CRM > Configuration > Sales Teams - Create two Sales Teams - Go to CRM > Configuration > Stages - Create multiple stages specific to each team - Make the current user belong to both teams - Go to CRM > Leads - Create a new lead (stage is assigned here) - Change its Sales Team - Lead stage is not updated according to the team **Issue:** The `stage_id` of `crm.lead` is never updated after it is set. This means that changing the related team will not modify the possible stages of the lead (even if it should not be available to the current team). **Fix:** Check if the team of the lead is the same as the one of its current stage during `_compute_stage_id`. opw-4901009 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232136
This update refreshes the websocket-client package used by the IoT box image to version 1.9.0. It helps prevent unwanted disconnections, improving the reliability of connected devices and reducing service interruptions.
Original PR description
This commit updates the PIP package websocket-client to 1.9.0 to fix disconnection issues. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235999 Forward-Port-Of: odoo/odoo#235748
This change removes an overly strict rule on tax group accounts, so users can again choose or copy tax groups even if the linked tax payable or receivable account has a different type. It restores flexibility without preventing users from updating the account type later if needed.
Original PR description
**Issue:** A constraint has been added to "account.tax.group" model some month ago, forcing a type for "Tax Payable Account" and "Tax Receivable Account" fields. However, some users had changed the type of these accounts or selected another one and they cannot do it anymore. They can't copy these tax groups neither. The constraint is too restrictive as we want to be more permissive. It's still possible to change the type of the account after selecting it for the tax group. Therefore, the constraint has some flaws. **Solution:** Remove the constraint. **Enterprise PR:** https://github.com/odoo/enterprise/pull/99421 opw-5231379 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235548
This change improves how fixed taxes are represented when invoices are exported, especially for UBL documents. It ensures different tax types are treated correctly, so exported invoices are more accurate and consistent for customers and tax authorities.
Original PR description
This commit contains 2 things: - an helper to extract any tax_data and move it to another base_line - the usage of this helper in UBL to turn emptying taxes into additional base_lines == Add helpers…
This commit contains 2 things: - an helper to extract any tax_data and move it to another base_line - the usage of this helper in UBL to turn emptying taxes into additional base_lines == Add helpers to turn tax_data into new base_lines easily == With this helper, you can now exclude any tax from any base line and turn them into new base lines. Also, I changed a bit the smooth distribution of rounding because the math.ceil is sometimes too greedy and make the whole results to be less accurate. == Make a different behavior between recycling contribution taxes / emptying taxes == In UBL, all fixed taxes are treated as allowances/charges. In this commit, we make a clear distinction between recycling contribution taxes that are treated as allowances/charges and emptying taxes that are exempted of tax and are treated as addition invoice lines in the document. == Fix a small issue with aggregate_function passed to reduce_base_lines_with_grouping_function == The aggregator wasn't called when setting the 'target_base_line' at the very first time. task_id: 5182783 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235580 Forward-Port-Of: odoo/odoo#234489
This fix ensures that products shown in the add-to-cart pop-up only belong to the website the shopper is currently browsing. It prevents customers from seeing optional products that are not available on that site, reducing confusion and avoiding incorrect product offers.
Original PR description
Steps to reproduce: =================== 1- Create another website 2- Sales app > Products > Open any product's form 3- In the Optional Products field, select any other product in your database for this field 4- Open the product form of the optional product you selected 5- Set the Website field to only be one of your websites, rather than All 6- Navigate to the Website app > Select the non set website in the other Steps 7- Open your shop > Select your main product > Click the add to cart button -> See the optional product appear in the pop-up. Cause: ====== _should_show_product function doesn't validate if a product is available on the website from which the request originates when handling multiple websites. Solution: ========= Update the function to take multiple websites into consideration opw-5179894 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233170
This change prevents an error in payroll processing when a payslip date is missing or empty. The system now safely handles those cases instead of failing, reducing interruptions for users and improving reliability.
Original PR description
The assertion was added to prevent the use of the _is_overlapping_period function with null or False dates. Which fixes an exception caused when a payslip's date was false/null. Related to odoo/enterprise#97013 task-5159666 Forward-Port-Of: odoo/odoo#231247
This fix ensures that when the account on a vendor bill line is changed, any linked non-deductible product line is updated to use the same account. This prevents mismatches between related accounting entries and helps keep bills consistent and correctly posted.
Original PR description
When you have a vendor bill with an invoice line linked to a journal item with the display type "non_deductible_product", if you modify the account_id of the invoice line, then the account_id of the…
When you have a vendor bill with an invoice line linked to a journal item with the display type "non_deductible_product", if you modify the account_id of the invoice line, then the account_id of the linked line should change to have the same value.
How to reproduce?
1. Create an asset model (Accounting > Configuration > Accounting > Asset Models)
2. Set the asset_model_id on an account (on the tab "Automation", set "Automate Asset" as "Create in draft" then set the "Asset Model" field with the created asset model
3. Duplicate the account having the created asset model
4. Create a vendor bill with an invoice line having:
- A strictly positive price unit
- A deductible_amount (Professional %) lower than 100 (this field is hidden by default)
5. Modify the account_id of the invoice line
6. Observe the journal items: the line with the non- deductible product should have the same account_id than the invoice line but it's not the case.
task-5156256
Forward-Port-Of: odoo/odoo#232121This fix resolves an issue where the status bar could show empty dropdowns after selecting a stage when not all items fit on screen. It ensures the hidden stages are properly included in the dropdown, so users can reliably change statuses without missing options.
Original PR description
Since PR [1], there was an issue with the statusbar field and the way it put overflowing items into dropdowns (cf. adjust function). Have a form view with a statusbar field and enough items s.t. they…
Since PR [1], there was an issue with the statusbar field and the way it put overflowing items into dropdowns (cf. adjust function). Have a form view with a statusbar field and enough items s.t. they don't all fit in the screen. The widget implements a logic to put the first and/or last overflowing items into dropdowns (one before the displayed items, one after). Before this commit, if the user clicked on an item to select it as new value, the state of the widget was incorrect, leading to dropdowns being displayed, but empty (and items being unavailable, as they are hidden, but not displayed in the dropdown). This was due to a `useEffect` with an incorrect dependency: if two consecutive renderings were done with the `shouldAdjust` status (which is possible since [1] and the introduction of the `forceRecomputeItems` flag), the dependency didn't change and the callback of `useEffect` was not called, leading to items not being processed. [1] https://github.com/odoo/odoo/pull/230548 opw~5232448 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 .dat export for Philippine reports now uses the same date range as the report filter, so the file period and the report data stay consistent. A non-blocking warning also helps users notice when the selected export period does not match the report period, reducing the chance of confusion or incorrect filings.
Original PR description
Before this commit: - The `.dat` export adjusted its date based on the selected export type’s periodicity (quarterly or annually) using the report filter's date_to. - This caused mismatches where the…
Before this commit: - The `.dat` export adjusted its date based on the selected export type’s periodicity (quarterly or annually) using the report filter's date_to. - This caused mismatches where the `.dat` file showed a different period than the report data. - The adjustment only changed the date in header of `.dat` file but did not restrict data accordingly, leading to inconsistencies when exporting reports with different filter and periodicity types. - Example: If the report filter is set to 'October 2025' month and the export type's periodicity is 'Annual', the `.dat` file would show 12/31/2025 even though the data in `.dat` file only covers 'October 2025'. Similar mismatch occurs for 'month & quarter' and 'annual & quarter' combinations. After this commit: - The `.dat` export date now fully depends on the report’s date filter, keeping report data and export date consistent. - A non blocking warning is added in the `.dat` export wizard when the report period type is different from the export type's periodicity, helping users select the correct period type while still allowing export if intended. task-5172259
This update fixes an issue where some accounting and localization workflows could proceed without a bill date being properly required. It helps ensure invoices and related reports behave consistently, reducing the risk of incomplete or incorrect billing information.
Original PR description
task-5214234
This fix corrects the unit of measure shown for finished products in manufacturing orders when the bill of materials uses a pack-based unit. It helps ensure the produced quantity is recorded and displayed accurately, avoiding confusion during production validation.
Original PR description
**Steps to reproduce:** - Create a bill of material for a product tracked by lot - Modify the uom on the bill of material for that final product to 'pack of 6' - add any component that you like - Create a manufacturing order for the final product - Generate a lot number and validate the production order **Issue:** The unit for the final product is incorrect. Task: 5232897 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Pay Category field is no longer mandatory for employees and contract templates, which helps cases like freelancers or people without an occupation avoid unnecessary setup. Employees without a Pay Category will be excluded from pay runs, and the form text has been updated to make this clearer.
Original PR description
The field is always required in the employee and contract template form views, but a Freelancer, or people without occupation should not bother with it. There was a check on the pay category during the payslip creation which is now removed since the payslip is computed based on the pay structure on the payslip form not the one on the employee profile. Employees without a pay category will be excluded from pay runs, therefore the "Pay Category" placeholder in form views has been updated to indicate so. Task-5237800
Vendor bills will no longer automatically use today’s date when the date is left blank. This helps avoid accounting mistakes that can affect VAT periods and tax deductibility, since the bill date often differs from the posting date.
Original PR description
Defaulting the bill date to today (behavior since 19.0) is error-prone for accounting (e.g., VAT periods, deductibility) as the bill date rarely matches the posting date. This commit restores the validation error if the date is empty on vendor bills, forcing a user to enter the correct date. task-5214234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change prevents an error that could occur when a user deletes the value in a pricelist rule’s base price field and then saves. It improves the reliability of pricelist editing in the website sales flow and avoids an interruption for users configuring pricing rules.
Original PR description
Currently, an error occurs when user removes value from `Based On` field and saving. Steps to replicate: - Install `website_sale` with demo and enable pricelists from settings. - Open pricelists and…
Currently, an error occurs when user removes value from `Based On` field and saving. Steps to replicate: - Install `website_sale` with demo and enable pricelists from settings. - Open pricelists and Open any Pricelist. - Under the pricelist rules, make sure `Price Type` is selected as Formula. - Remove value from `Based Price` and click elsewhere. Error: `KeyError: False` Cause: - As the `base` field was changed the compute was called and `item.base` was passed on as 'False' at line [1] and caused the Keyerror. Solution: - The code skips execution when `item.base` is False, as there is no point in making the `item.rule_tip` [2] if we dont have all the values. [1]: https://github.com/odoo/odoo/blob/257537584bedc1ab7db1bdc700f89145a3bb6095/addons/product/models/product_pricelist_item.py#L287 [2]: https://github.com/odoo/odoo/blob/257537584bedc1ab7db1bdc700f89145a3bb6095/addons/product/models/product_pricelist_item.py#L284-L296 sentry-6948941509 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When merchants replace a product image in the website editor, the uploaded image will now keep a high-resolution quality instead of being reduced to a blurry, compressed version. This improves the appearance of zoomed product images and avoids visible compression artifacts for customers.
Original PR description
Versions -------- - 19.0+ Steps ----- 1. Have a browser open with a side-bar or that isn't full-screen; 2. open website editor on a product page; 3. enable zoom-on-click; 4. replace the main image;…
Versions -------- - 19.0+ Steps ----- 1. Have a browser open with a side-bar or that isn't full-screen; 2. open website editor on a product page; 3. enable zoom-on-click; 4. replace the main image; 5. save changes; 6. click on the new image to zoom in; 7. download the image. Issue ----- The image is too small & low quality. Cause ----- The `this.dependencies.media_website.replaceMedia(image)` call is meant to be used along with an html editor widget to select size & quality. As we have a custom widget to handle product images, the image that ends up getting uploaded is one that's been optimized for the current viewport size. Solution -------- Replace the `replaceMedia` call with custom logic similar to that used for extra media, drawing the image to a `canvas` element, and then saving it as the product's `image_1920` field. Additionally, enable extra media to get saved as in 1920 size, and remove the hardcoded `0.75` image quality value, as a value this low easily leads to visible compression artifacts. opw-5088032
This change prevents a report page from briefly reloading with outdated settings when switching between report variants. It fixes an error that could appear in composite reports, making report navigation more reliable for users.
Original PR description
This fix a traceback: - Create a report "A" with Period Comparison set to True - Create a report "B" with Period Comparison set to False - Create a composite report with report "B" inside. - Use the…
This fix a traceback: - Create a report "A" with Period Comparison set to True - Create a report "B" with Period Comparison set to False - Create a composite report with report "B" inside. - Use the variant filter to switch from report "A" to the composite report This happens because of a UI refresh in `loadReportOptions` trigged by: - delete this.reportOptionsMap[cacheKey]; - delete this.loadingCallNumberByCacheKey[cacheKey]; When refreshing the UI, it will start with the cachedOption set to the value of the displayed report (report "A"), and is able to pass the condition inside `filters.xml`: `<t t-if="controller.filters.show_period_comparison">`. While this is happening, the loading of the new report "composite" reaches `this.cachedFilterOptions = options;`. However, the UI refresh is still ongoing, and when it reaches `<t t-if="controller.cachedFilterOptions.comparison.string">` in `filter_comparaison.xml`. If the new report doesn't have the comparaison filter enabled, cachedFilterOptions.comparison will be undefined triggering the traceback. This is fixed by marking the objects, that would trigger this useless refresh, as raw preventing them from triggering a refresh. This only happened on composite reports since the cacheKey used to load them is different from the one received by the call to get_options due to the sections. task-5085985
The cart pop-up now respects the website’s tax display preference, so prices shown after adding a product match whether taxes are included or excluded. This avoids confusing customers with a notification that shows a different price style than the rest of the shop.
Original PR description
Versions -------- - 19.0+ Steps ----- 1. Set website preference to display taxes price-included; 2. add a product to your cart. Issue ----- The notification displays the product's price tax-excluded. Cause ----- Commit 8dac8f3 updated the cart notification to display the amount of the recently added quantity, instead of the product's total amount. It did this by removing the check on `show_line_subtotals_tax_selection` and simply display the line's `price_unit` times the added quantity. Solution -------- If `show_line_subtotals_tax_selection` is set to `tax_included`, calculate a tax-inclusive unit price by dividing the line's total by the line's quantity. opw-5214094
Offers created from the manual "New" flow will now always get a valid access link, matching the behavior of offers generated from an applicant. This fixes broken links that could previously open with no token and ensures the right people can access offer details safely.
Original PR description
#### Steps to Reproduce - Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list…
#### Steps to Reproduce - Go to Recruitment > Applications > All Applications. - Open an applicant form and click "Generate Offer". - Repeat a few times so that the "Offers" smart button shows a list view. - From the list view, click "New" to create an offer. - Compare both flows: * With "Generate Offer" button: the generated offer link has a valid token and works even in an incognito window. * With "New" button: the generated offer link has `token=False`, which leads to an invalid link. #### Issue In the first scenario, `action_generate_offer()` generates an `access_token` for the offer's link in `hr.applicant`. In the second scenario, no token was generated in `hr.contract.salary.offer`, so offers created via the "New" button end up with `access_token=False` in their links. #### Fix - Add a compute to `access_token` in `hr.contract.salary.offer` to generate a token if there is no employee or if the employee on the offer has no linked user. - Update controller logic to prevent public users from accessing an offer link if the offer's employee has a linked user. task-5051394
This update fixes an issue that could prevent non-admin users from exporting contacts. It ensures the export process can read the necessary property information, so users with limited access can complete the export normally.
Original PR description
Step to reproduce: - login as "demo" user - Go to Contacts - Selected 1 or more contact, - click on ☸Actions dropdown and click on ⬆Export option Cause - Issue introduced after [1] commit, as now we allow property field in `res.partner` using `properties.base.definition` model. - This model only allows admin and hence demo user cannot access the defination model when evaluating properties field. Fix: - Use sudo(), allow access to property_defination model. [1]:https://github.com/odoo/odoo/commit/9bf0107fb72e7adcbad926a6749bdd0537d24418 opw-5245978 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website editor now correctly identifies the menu section when enabling eCommerce categories in a mega menu. This prevents an error that could stop the option from working after recent editor layout changes.
Original PR description
When we toggle the e-commerce categories in the mega menu option, an error occurs. This happens because the `toggleFetchEcomCategories` action gets the first child of the editing element, which used to be the section we target, but after this [commit] has added the selection placeholder, the section is no longer the first child. Steps to see the issue: - Open website and create a mega menu - Start the edit mode - Click on the mega menu you just created - Toggle eCommerce categories in the 'Mega Menu' options container -> We receive an error: `Template not found: 'website_sale.undefined' (website: None)` [commit]: https://github.com/odoo/odoo/commit/edf7f7bb0c62978640c181e task-5268995
Live chat visitors will no longer see the option to start a call. This fixes an access control issue where authenticated portal users were incorrectly treated as eligible for call actions, ensuring only internal users can use this feature in live chat conversations.
Original PR description
Before this commit, portal visitor could start a call in livechat. This comes from bad condition for start call button, which was only checking the current user is a guest. Portal users are authenticated and don't have guest, so they were mistakenly elligible for "Start Call" button. This commit restrict the button further to not show only for internal users in livechat conversations.
This fix prevents a crash when calculating purchase price on sales lines that have no delivered or ordered quantity, or when return quantities would make the calculation invalid. In those cases, the system now safely falls back to the standard cost, keeping sales margins consistent and avoiding interruptions for users.
Original PR description
Steps to reproduce: - Install 'sale_stock_margin' module - Create SO > Create product with category -> 'Costing Method' : 'FIFO' - 'Confirm' SO > Change product 'Quantity' to zero Traceback:…
Steps to reproduce: - Install 'sale_stock_margin' module - Create SO > Create product with category -> 'Costing Method' : 'FIFO' - 'Confirm' SO > Change product 'Quantity' to zero Traceback: ZeroDivisionError: float division by zero At [1], this error occurs because both 'product_uom_qty' and 'qty_delivered' are '0', resulting in a denominator of zero, which is not allowed. [1]: https://github.com/odoo/odoo/blob/a884794ebfc8145c61bb34908093f00246f224ff/addons/sale_stock_margin/models/sale_order_line.py#L23 Issue also occurs when 'product_uom_qty' = 0 and 'qty_delivery' < 0 since `qty_from_delivery + qty_from_std_price` = 0 in this case. Expected result: - If both `product_uom_qty` = `qty_delivered` = 0 => fallback on standard_price (default behavior when only `sale_margin` installed) - If `qty_delivery <= 0` => fallback on `standard_price` to avoid inconsistent values for return moves, i.e. value would vary depending on whether or not the return is linked to a delivery (i.e. `price_unit_from_delivery`) whereas a return not linked to a delivery will default to `standard_price` sentry-6978885438 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The system now treats bank accounts without a currency as equally suitable when choosing a default account. This fixes a case where multi-currency setups could not use a no-currency bank account as the default, making account selection more reliable.
Original PR description
In 656a26c309dae58e0f680421311a11344d72b1f5 , we prioritized bank accounts with a strict currency match over accounts with no currency. That's problematic for a multi-currency account, as leaving currency empty is normal; in that case, it's impossible to set it as the default. Updated sorting priorities as the no currency account is at the same level of priority as the currency match. task-5322123 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue that could prevent videos from being uploaded to YouTube because a browser error was blocking the process. It also modernizes the upload logic so the feature works more reliably going forward.
Original PR description
Issue: when trying to upload a video to youtube, we receive an error as "ReferenceError: $ is not defined" meaning we're not able to reach the jQuery identifier. So following the trend we're moving away from jQuery, this commit removes the usage of jQuery in the youtube upload field. - Replaced $.ajax() with fetch() in _openUploadSession, _updateProcessingInfo, and _onClearClick methods - Replace $.ajax() with XMLHttpRequest in _uploadFile to maintain upload progress tracking opw-5142810
The livechat info side panel now shows the chatbot answers for the selected conversation instead of pulling replies from a more recent session. It also hides blank chatbot entries, making the panel clearer and easier to read for support teams and visitors.
Original PR description
**Description of the issue this PR addresses:** The info side panel in livechat displayed incorrect or empty chatbot answers for previous sessions. 1. When a visitor used the same chatbot multiple times, the panel showed answers from the latest session instead of the selected one. 2. when a user skipped a question, the panel still displayed an empty line with a comment icon. **Current behavior before PR:** 1. Chatbot answers were fetched using an incorrect query that didn’t consider the specific livechat session or channel. 2. Empty chatbot responses appeared in the side panel. **Desired behavior after PR is merged:** 1. The correct chatbot answers for the selected session are now shown in the info side panel. 2. Empty chatbot answers are hidden. task-[4981175](https://www.odoo.com/odoo/project/1519/tasks/4981175) Forward-Port-Of: odoo/odoo#231205
This change fixes a case where imported supplier refunds could be incorrectly reclassified after matching to a purchase order. It ensures the original refund type is preserved, avoiding accounting mismatches and making imported documents more reliable.
Original PR description
The `move_type` is changed after PO match. This PR fixes the case of import a refund that matches a PO so the `move_type` is not changed after matching. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#235879 Forward-Port-Of: odoo/odoo#233907
This update fixes an issue where payroll calculations could use the wrong rule version because payslip dates were not properly taken into account. It also removes an automatic start-date default that could be incorrect for manually created single payslips, helping ensure more reliable payroll results.
Original PR description
Current version_id computation does not depend on payslip dates, which could very often lead to wrong calculations, in this PR we solve this by removing the cyclic dependency between dates and version compute by removing the default computation of the date_start, which is often wrong anyway in the case of a single manual payslip Forward-Port-Of: odoo/enterprise#95257
This update fixes how Northern Ireland tax rules and fiscal positions are installed and activated, so they now work correctly when Northern Ireland is selected. It also corrects tax mapping to better match the applicable regulations, helping avoid compliance issues in accounting.
Original PR description
Before, the chart template for Northern Ireland was not automatically installed. Also, the specific NI taxes and fiscal positions would not be activated using the NI country. It would only be activated by using an NI state with a UK country. Another issue was the tax mapping with fiscal positions, which was wrong. It is now fixed to ensure compliance with the actual regulation. task-5276600
The Reviews button on an employee profile now correctly shows contract review records instead of opening an empty page. This restores access to both active and inactive records, so users can see the full review history as expected.
Original PR description
Issue:
When an offer is created and signed by the employee, the `Reviews` smart button appears on the employee profile. Although it indicates that there are records, clicking the button redirects to an empty list.
Reason:
After converting contracts to the versioning system, the action for the Reviews button does not properly display contract versions, regardless of whether they are active or inactive, as it did in the previous version.
Fix:
Added a context `{"active_test": False}` to show active or inactive records.
task-5155455
Forward-Port-Of: odoo/enterprise#96808This change fixes an issue where adding an image to a grid element could cause the page to keep loading indefinitely. It improves the website editor experience by ensuring image insertion finishes correctly, especially for GIF and SVG images.
Original PR description
The action for adding an image was waiting on the `load` event on the image, but it may have already occurred, thus the promise would never resolve. With this commit, we do not wait if the img is already `complete`. Steps to reproduce (non-deterministic): - Open website builder - Click on a grid element (for example a "Banner" snippet) - Click on "Image" in "Add Elements" option - Add an image (it seems more likely to trigger the bug with a gif) - Bug: The dialog closes, and an infinite load follows task-5187071 opw-5167545 Forward-Port-Of: odoo/odoo#232818
Users can now revoke SEPA Direct Debit mandates even when they have been used with saved payment methods from the customer portal. This fixes an access issue that previously blocked non-admin accounting users from completing the revocation process.
Original PR description
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** -…
**Issue:** As a user without "Administration / Settings" access, it is not possible to revoke SEPA Mandates that have been used to pay invoices through the customer portal. **Steps to Reproduce:** - Enable SEPA Direct Debit payment provider in Test Mode - Create a mandate for a customer w/ valid IBAN - Create an invoice for that customer and post it - Action > Generate a Payment Link, open this in an incognito window - Pay using SEPA Direct Debit - Call `_set_done()` on the payment.transaction - Try to revoke the mandate as a non-admin with "Accounting / Billing" -> Access Error, can't modify payment.token **Cause:** - When SEPA Mandate is revoked, we check for all associated payment tokens (saved payment methods from SEPA Direct Debit payment provider) and deactivate them. - The check in code isn't called with sudo, so it uses the current user access rights, but only admins can modify the payment tokens in any way. **Solution:** - Write to the `linked_tokens` with sudo so we can archive the tokens regardless of user access opw-5136221 Forward-Port-Of: odoo/enterprise#99592 Forward-Port-Of: odoo/enterprise#99232
This change makes website page addresses work correctly when they contain certain non-Latin characters. It prevents pages from showing a 404 error when users type or paste the URL in browsers like Safari.
Original PR description
Scenario: - create a page with url "가" (\N{HANGUL SYLLABLE GA}) then in safari: copy the url to open it in a new tab => a 404 error is shown in all browser: go to /가 writing it manually => a 404…
Scenario:
- create a page with url "가" (\N{HANGUL SYLLABLE GA})
then in safari: copy the url to open it in a new tab => a 404 error is shown
in all browser: go to /가 writing it manually => a 404 error is shown
Cause:
We decompose the unicode combination to remove diacritics, but never
recompose them, so we save the slug
\N{HANGUL CHOSEONG KIYEOK}\N{HANGUL JUNGSEONG A} (NFD normalization)
instead of \N{HANGUL SYLLABLE GA} (NFC normalization). Those appear
exactly the same, but when typing you would usually use the NFC one.
Comparing other software, they usually convert NFD to NFC but not the
other way.
When you use the address bar in safari, the URL is normalized with NFC
so you can't type or copy paste a NFKD path to get to it (and can only
get to it by link).
But the issue still exists for other browser where you will usually
manually type NFC and not NFKD.
This is not reproduced, but this could also have effect with search motor
that would normalize link content.
Fix:
When creating slug, normalize to NFC after the removal of diacritics.
opw-5184532
__pr note:__
the original ticket also reported about removal of diacritical mark in Vietnamese and Japanese, but this seems a more of a feature for master change since we have had "éléphant" becomes "elephant" since forever.
other services that allow unicode in path (such as wordpress, wix) seems to just keep the diacritics and normalize to NFC even if the input was in NFD.
for NFD / NFC explanation: https://docs.python.org/3/library/unicodedata.html#unicodedata.normalize
Forward-Port-Of: odoo/odoo#234416