Daily updates from Odoo
Monday, October 13, 2025
40 changes · saas-18.3
Resolved issues and error corrections
The Indian localization test setup was adjusted so standalone tests no longer depend on the US accounting module when demo data is unavailable. This reduces test failures and improves reliability for maintaining the Indian localization without affecting end users.
Original PR description
Standalone `l10n_in` tests were failing when running without demo data because outside-India companies (e.g., US) were defaulting to their country-based chart of accounts. This required the `l10n_us_account` module, causing errors when the module was not installed. <img width="518" height="28" alt="image" src="https://github.com/user-attachments/assets/748663a0-f329-459c-b0e8-0c3de7019258" /> This commit adapts the test cases to run without l10n_us_account dependency. task- 5116352 Forward-Port-Of: odoo/odoo#230041
The commission achievement report now uses the latest end date from relevant commission plans as the default in all cases. This prevents reports from accidentally covering too short a period, helping sales teams and managers see complete commission results.
Original PR description
When there is active_plan_ids in the context the date_to are the max of plans' date_to when not it's the min, this is wrong it should be the maw as well
This fix improves commission reporting reliability by ensuring related adjustment logs generate distinct achievement records. It prevents rare duplicate identifier collisions that could cause commission achievements to be merged or reported incorrectly.
Original PR description
This commit 5b6fdda126e4cfa5ebf92f7b96d1805f6c4b992b introduce an entropy date to avoid having two separate achievment.report record with the same ID. Entropy date for log where based on the write_date, this commit 03d1ee3495a4936fbff0d21743bb784c85b50b12 add the sign of the amount. Unfortunatly this is not enough, the adjustment after the transfer can be positive as well and thus two achievment ends-up with the same ID anyway. This commit use the id of the log to add more entropy to the entropy_date, since log are created in the same transaction, they are likely to have id just seperate by one or only few number, id % 10 seems enough, therefore two log on the same order, with the same create_date will have different entropy date and end up with a different id.
This fix preserves barcode scanning settings when a warehouse batch transfer is confirmed. It prevents location barcodes such as WH-Stock from being misread character by character, helping warehouse staff continue batch picking without scan failures.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
This update adds safeguards so Danish Nemhandel connections are neutralized in non-production copies. Existing proxy clients are switched to demo mode, and new registrations use the test server to avoid unintended live sending or registration.
Original PR description
To avoid sending/registering on production, add a neutralize script. The existing proxy client are put in demo mode. The new connections will be registered on the test server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229934
Point of Sale payments made through a payment terminal now complete automatically when cash rounding is applied. This prevents staff from having to manually validate fully paid orders, reducing missed validations and checkout mistakes.
Original PR description
Ensure that when a payment is made via a payment terminal and cash rounding is applied, the payment is automatically validated once the response is received. Previously, validation did not always occur because we relied on `get_due` is not exactly what is left to pay, as it does not account for cash rounding rounded amounts. The condition for auto-validation was simplified, since `is_paid` already checks whether there is nothing left to pay. Thus, using `get_due` is redundant. Steps to reproduce: 1. Create a cash rounding and set it on the POS. 2. Sell a product priced at e.g. 1.99 EUR, paid via a terminal (e.g. Worldline). 3. Notice the payment is not auto-validated and requires manual validation, which can lead to mistakes or missed manual validations. opw-4862684 Forward-Port-Of: odoo/odoo#231034 Forward-Port-Of: odoo/odoo#228608
This fix prevents the mail system from crashing when it receives an incorrectly formatted email address without an '@' symbol. It makes email alias handling more robust, reducing the chance of interruptions caused by malformed incoming emails.
Original PR description
Just be sure emails contain at least an '@', otherwise partition may crash. Forward-Port-Of: odoo/odoo#231171
Fixes an issue where lunch orders could be archived by mistake when users clicked Receive more than once or placed another order for the same product. This keeps order lists accurate and prevents confusion around received lunch orders.
Original PR description
**Issue** The lunch order merge logic was causing orders to be unexpectedly archived when they shouldn't be. Users would see their orders disappear from the list view after certain operations like…
**Issue** The lunch order merge logic was causing orders to be unexpectedly archived when they shouldn't be. Users would see their orders disappear from the list view after certain operations like clicking "Receive" multiple times or when trying to merge orders with existing ones in immutable states. **Steps to Reproduce** 1st problem - Create a lunch order - From the order list view, select the order and click the "Receive" button - Select and click the "Receive" button again on the same order - The order gets archived and disappears from the view 2nd problem - Create a lunch order - From the order list view, select the order and click the "Receive" button - Place another order for the same product as before - From the order list view, once the second order is set to received, it gets archived and the update quantity logic not triggered **Root Cause and Solution** 1st problem: When searching for matching orders to merge, the current order being processed could match itself, leading to self-deactivation. Fixed by adding matching_lines = matching_lines - line to exclude the current record from potential merge targets. 2nd problem: The merge logic was trying to combine new orders with existing "sent" and "confirmed" orders, but the update_quantity method correctly excludes these states since they shouldn't be modified once sent/received. This created a mismatch where orders would be archived but quantities wouldn't update. Fixed by excluding "sent" and "confirmed" states from merge target searches entirely. Task ID: 5123211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229084
This fix corrects how Maltese fiscal positions map taxes for EU and non-EU partners. It ensures sales taxes map to sales taxes and purchase taxes map to purchase taxes at matching rates, reducing the risk of incorrect tax treatment in Maltese accounting.
Original PR description
### Steps to reproduce: - Install "l10n_mt" and switch to a Maltese company - Check the fiscal position "EU Partner", it maps Sales taxes to Purchase ones - "Partner outside the EU" maps Purchase taxes to Sales ones ### Solution: Fix the CSV. We map the taxes respecting Sales/Purchase and with the same percentage. opw-5065298 Forward-Port-Of: odoo/odoo#230515 Forward-Port-Of: odoo/odoo#227423
Equipment pages now open reliably even when a completed maintenance request has had its repair dates cleared through customization or manual changes. The system treats missing dates safely instead of showing an error, reducing disruption for users viewing equipment records.
Original PR description
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them…
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them from opening equipment views that displayed fields that depended on it. Steps to reproduce: - Create new maintenance request for an equipment - Put maintenance request into a `maintenance.stage` where `done=True` (e.g. "Repaired") - Force `close_date` to not be `readonly` in form view + set it to `False` - Try to open the assigned equipment's form view Expected result: Form view opens without issue Actual result: `unsupported operand type(s) for -: 'bool' and 'datetime.date'` Issue was due to `mttr` calculation in `_compute_maintenance_request` not expecting `close_date` to be `False`. Since we want the request to still be considered for the rest of the compute, we count its "Time to Repair" as 0 in this case since we cannot use infinity in this case. Additionally, we also gracefully fail in the same way in case `request_date` is also forced to be `False` since it is not a mandatory field and can cause the same issue. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230942 Forward-Port-Of: odoo/odoo#230821
This update prevents an error when users hide a rich text field that contains newly added images before saving. It helps keep form editing smooth and avoids interruptions in Studio-configured views.
Original PR description
**PROBLEM** When hiding a HtmlField field from a view with pending images in it, there is a traceback. **STEP TO REPRODUCE** 1. Using studio, create a HtmlField on the view of your choice. 2. Add a…
**PROBLEM** When hiding a HtmlField field from a view with pending images in it, there is a traceback. **STEP TO REPRODUCE** 1. Using studio, create a HtmlField on the view of your choice. 2. Add a checkbox next to it, and link the HtmlField visibility to the button. 3. Add a image to the HtmlField (don't save the record !) 4. Hide the HtmlField using the checkbox, there should be a traceback. (if not, try with a bigger image). **CAUSE** commitChanges() will try to retrieve the field value to commit by looking at the related element in the DOM. Before retrieving this value, we call savePendingImages() to save the new images added to the HtmlField. https://github.com/odoo/odoo/blob/1416aad902a97ce56aaecc2aadc4dd9f7814ee53/addons/html_editor/static/src/fields/html_field.js#L159-L162 This introduces a delay, during which the DOM element could be destroyed. **FIX** We don't call commitChanges() in OnBlur(). Instead, we cache the new value in a property of HtmlField called `newValue` when `OnChanges()` is called. Inside OnBlur(), we save the pending images by directly calling `savePendingImages()` and we commit the new value by calling `updateValue(this.newValue)` opw-5061820 Forward-Port-Of: odoo/odoo#227482
Employee contracts in multi-company setups now only show insurance records belonging to the relevant company. This prevents users from accidentally selecting another company's insurance, improving payroll data accuracy for Swiss ELM transmissions.
Original PR description
Currently, in a multi-company setup, you are able to select insurances from other companies on the employee contract task-5157106 Forward-Port-Of: odoo/enterprise#96821
This fixes a sales module issue where automated checks could fail when a custom field was placed before the product field on sales order lines. The change makes the product configurator test steps more robust, helping ensure custom sales order layouts do not cause false test failures.
Original PR description
To reproduce: 1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:…
To reproduce:
1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:
https://github.com/odoo/odoo/blob/18.0/addons/sale/views/sale_order_views.xml#L521 making the field `display_type` visible
2. Run the tests of `sale` module
=> `sale` module tests will fail on test `test_sale_combo_configurator_preconfigure_unconfigurable_ptals`
```
FAILED: [18/22] Tour sale_combo_configurator_preconfigure_unconfigurable_ptals → Step Verify that configurable ptals are now configured (trigger:
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")).
Element (
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")) has not been found.
TIMEOUT step failed to complete within 10000 ms.
```
see runbot build fail at:
https://runbot.odoo.com/runbot/build/89552334
The issue happen as - for some dark magic JS/XML reason - adding the field before product_id make fail the step to click the checkbox using the span.
Fix was suggested by PIPU to solve/workaround the issue
In practice, this issue was discovered accidentally with a customisation which was willing to add a custom field at the start of the list
opw-5068699
Forward-Port-Of: odoo/odoo#228029Shipping label printing can now use a selected printer for each delivery operation type instead of automatically using the first compatible printer. This helps businesses route labels to the right printer by workflow or warehouse area, reducing misprints and manual intervention.
Original PR description
Printing shipping labels is performed from the backend, once the shipping info are received in the chatter. The printing command is sent to the frontend via the user bus, then though longpolling to the iot box. This commit adds the possibility to select a printer instead of choosing automatically the first (with the right report associated) on the list. As the change is made on a stable version, we are using system parameters to store the selected printer without adding a new field. We associate a printer with the picking type, in order for to be able to have different printers by default on different picking types. Task: 4792491 Forward-Port-Of: odoo/enterprise#95603 Forward-Port-Of: odoo/enterprise#86818
Invoices eligible for an early payment discount are no longer incorrectly marked as fully paid when only a partial payment is received. The paid amount is applied correctly, keeping the invoice partially paid and avoiding incorrect suspense account entries.
Original PR description
Problem: If partial payment is done for Invoice which is eligible for early payment discount, Invoice is marked as paid and remaining amount is debited in suspense account. Cause: While preparing credit entry for receivable account, only eligibility of Invoice for early payment discount was checked and whole residual amount of Invoice is credited instead of amount which is paid, and this is done for partial payments also(which shouldn't be done). After this commit: If partial payment is done for Invoice which is eligible for early payment discount, Invoice is marked as partially paid and only amount which is paid is credited from receivable account and nothing in suspense account. task-5128802
Fixed an issue where point-of-sale payment shortcut buttons could add the wrong amount for users whose language uses a comma as the decimal separator. This prevents inflated payment totals and helps cashiers process payments accurately in affected locales.
Original PR description
**Steps to reproduce:** - Set your database in a language with a "," as a decimal separator, such as French - Make a purchase, chose a payment method - Before paying, click any +10/20/50 button - The…
**Steps to reproduce:** - Set your database in a language with a "," as a decimal separator, such as French - Make a purchase, chose a payment method - Before paying, click any +10/20/50 button - The price will be multiplied by 100, then add the desired amount **Why the fix:** There were two places where the decimal separator was causing issues. First when we try to get the current price, *currentBufferValue*, we try to get it when it's in float state, but as we have a language with a decimal separator set as "," the "." in this float will be ignored, and we will take the decimal as units as well, explaining the *100 amount, because the decimals become whole numbers. Secondly, when we try to make the addition of the two and convert it to string again, the *toString* method will convert it with a default "." not taking the current decimal separator into account. Once again, the "." will be ignored later on, leading to an even more over the top number. We now convert the numbers and the strings using the correct decimal separator. opw-5126224
Auto-forwarded emails could incorrectly add extra recipients as followers when alias matching was configured to use the email name before the @ sign. This fix restores the expected matching behavior so only the intended recipients are linked, reducing unwanted follower additions and notifications.
Original PR description
Sending an email that was auto-forwarded would lead to the recipient line having two different emails which would cause any emails that were not set up as aliases to be added as followers even if…
Sending an email that was auto-forwarded would lead to the recipient line having two different emails which would cause any emails that were not set up as aliases to be added as followers even if local part detection was enabled in the alias settings. This was due to the fact that partner detection was changed in 18.2 and now looked for exact email to alias matches. Ban emails were passed to the _find_or_create_from_emails and then directly matched to the emails in the list of recipient emails. When a match was not found for emails that did not have an exact matching alias_full_name, we would then look for or create a partner for that email. This caused erroneous followers to be added. Changing the functionality to also look for matching local parts in order to skip partner finding and creation reverts this functionality to how it previously worked where extra recipients with matching local parts when local part detection was enabled would not add those partners as followers. opw-4896074 Forward-Port-Of: odoo/odoo#216737
This update fixes display and filtering issues on website blog pages. Dates now line up correctly in list card layouts, and selected tag filters are preserved when users add, remove, or clear date archive filters.
Original PR description
This PR addresses the following issues: **Issue 1: Date Misalignment** **Steps to Reproduce:** 1. Navigate to website → Blog Page → Edit. 2. Change the layout from Grid to List. 3. Toggle the Cards…
This PR addresses the following issues:
**Issue 1: Date Misalignment**
**Steps to Reproduce:**
1. Navigate to website → Blog Page → Edit.
2. Change the layout from Grid to List.
3. Toggle the Cards button on.
4. The date and tags will appear slightly misaligned.
**Solution:**
Adding `#{` code in the `t-attf-class` attribute will align the date with the blog post content and tags.
**Expected Behavior:**
The date should align with the blog post content and tags preview.
**Issue 2: Some Tag Filters Getting Removed**
**Steps to Reproduce:**
1. Add a date filter from the sidebar of the blog.
2. Remove this filter by clicking the X button.
3. If multiple tags are present in the filter section, only the first tag remains while the rest are removed when the date filter is added or removed.
**Solution:**
Sending a POST request whenever the date filter is selected or removed. To achieve this, we introduced the `post_link` class to the `<select>` and `<a>` elements. When a date option is chosen, the click event triggers the `_onClickPost` handler
function, which extracts the URL from the `value` attribute of the `<option>` tag.
**Expected Behavior:**
All previously added tags should remain after adding or removing the date filter.
**Issue 3: All Tag Filters Getting Removed**
**Steps to Reproduce:**
1. Navigate to website → Blog Page → Turn On the Sidebar.
2. Select any tag from the tags section in the sidebar.
3. Ensure no blog is selected.
4. Select a date from the archives in the sidebar.
5. Change the date to '-- All Dates' in the archives dropdown.
6. All tags in the filter are removed along with the date.
**Solution:**
Removing the condition for navigation based on whether a blog is present or not will ensure tags remain in the filter section after selecting the '-- All Dates' option.
**Expected Behavior:**
Tags present in the filter section should remain after selecting the '-- All Dates' option.
task-3937884
Forward-Port-Of: odoo/odoo#230313
Forward-Port-Of: odoo/odoo#225845This fixes how fleet vehicles are marked when a driver is assigned a new or future vehicle. Other vehicles for the same driver are now marked as planned for change, while the vehicle being assigned is not incorrectly flagged, reducing confusion in fleet management.
Original PR description
WHen a new vehicle is created for someone in a non waiting column, we are settign his other cars in plan_to_change. When we set a future driver on a car, we set the others as plan to change, but not the one on which we are setting the future_driver --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prevents byte-based error details from being incorrectly displayed as a list of numbers in translated messages. Users will now see clearer, more readable error messages when certain system connections, such as email server tests, fail.
Original PR description
Improvements introduced by https://github.com/odoo/odoo/pull/197702 streamlined the auto formating of iterables to lists when passed as an argument to translatable strings in Odoo. While doing so,…
Improvements introduced by https://github.com/odoo/odoo/pull/197702 streamlined the auto formating of iterables to lists when passed as an argument to translatable strings in Odoo.
While doing so, strings were ignored (to prevent formating them as a list of the individual characters), but they failed to account for the fact that **byte strings** might also be passed as arguments in certain parts of the code.
An example can be found here:
https://github.com/odoo/odoo/blob/f037c39ad4d33384f81a418cb63fcdd6a5085d56/odoo/addons/base/models/ir_mail_server.py#L265-L278
`repl` in this context will be a byte string object returned by the SMTP connection.
## BUG:
Before the fix, if you would pass a byte string as an argument to a translatable string using keyword templating, the output would be the raw representation of the bytes as a list instead of the human readable content.
For example if we use in a french localisation:
`raise UserError(_('The server refused the test connection with error %(repl)s', repl=b'TEST byte string'))`
Before the fix we could get:
`Le serveur a refusé la connexion de test avec l'erreur 84, 69, 83, 84, 32, 98, 121, 116, 101, 32, 115, 116, 114, 105, 110 et 103`
And after the fix:
`Le serveur a refusé la connexion de test avec l'erreur b'TEST byte string'`
## Proposed fix:
In the same way that we ignore `str` arguments before auto applying the `format_list` method, we will also ignore them if the type is `bytes`
OPW-5107313
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prFixed an issue where certain dropdown menus could appear shifted when their contents were wider than the button opening them. This improves visual consistency and prevents confusion when users interact with menus in the web interface.
Original PR description
This commit fixes the position of the SelectMenu, that was not aligned properly when the content of the menu is larger than the toggler width before applying any maxWidth. Because the 'fit' variant sets the same width to the popper by default, and the code was applying this width after the computation of the position of the popper, the menu was displaced. Now, the width is applied before positioning the menu, which then computes accordingly. A test has been added as well. task-4674144 Forward-Port-Of: odoo/odoo#224568
The event form now correctly shows the community menu button when the Track Quiz feature is installed. This restores expected access for users managing event quiz-related community options, especially when the separate event meeting feature is not installed.
Original PR description
In the event form the "community" button is supposed to be shown when "track quiz" is installed. However when this was done in [1] there a mistake was made and only the label was removed, as well as the wrong field added after it. That field was removed in [2] but it was again not noticed that only the label was made visible. It may not appear easily because installing website_event_meet also unhides both the label and the field. Hence you only ge this issue when installing track quiz without it. However in 18.3 [3] removed website_event_meet which means the issue is not corrected anymore. task-5159806 [1]: https://github.com/odoo/odoo/commit/147cf5f328f5a55882a62a4279d1d92511628320 [2]: https://github.com/odoo/odoo/commit/c0f0f9f47573b74ca6b1fcdc3383e43f28f7a2e1 [3]: https://github.com/odoo/odoo/commit/9cab4f8f77f71e405971c184544765e8f252a012 Forward-Port-Of: odoo/odoo#231020
United Kingdom supplier or partner records are now assigned the correct DIOT country code instead of being grouped under “Other country.” This improves the accuracy of Mexican tax reporting and reduces manual review or correction needs.
Original PR description
The DIOT country adaptation map lacked the ISO 3-letter code for the UK, causing records with country 'GB' to be reported as 'ZZZ' ("Other country").
Added mapping 'GB' → 'GBR' to ensure correct DIOT country code generation.

Forward-Port-Of: odoo/enterprise#96771This fix makes follow-up report tests use a consistent date, preventing failures when tests run across midnight. It improves confidence in automated validation without changing business functionality for users.
Original PR description
Tests https://runbot.odoo.com/odoo/runbot.build.error/159772 where failing when setUpClass run before midnight and the test itself run at/after midnight because `today` was not the same. As follow-up report divides the lines per partner to due/overdue utilizing `today` in comparison, This resuls in different lines than expected. Forward-Port-Of: odoo/enterprise#96486
This update adjusts an internal test workaround for Gantt chart dependency behavior so automated checks remain usable after recent test framework changes. It is limited to the unit test ecosystem and does not change customer-facing Gantt functionality.
Original PR description
## Pull Request HOOT 37 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Community: https://github.com/odoo/odoo/pull/230556 Forward-Port-Of: odoo/enterprise#96647
The Analytic Reporting grid now keeps all months visible when users hide weekends in a yearly view. This prevents confusing missing-month reports because weekend filtering is only applied where it makes sense: month-level grids.
Original PR description
To reproduce: ============= 1- Go to Analytic Reporting. 2- From the year dropdown, uncheck "Show weekends". → Some months disappear unexpectedly. Problem: ========= Weekend filtering was applied even in year range. In year view, each column is already a full month, so filtering out weekends is incorrect. Fix: ==== Adjust the condition to skip filtering when range is not "month". Weekend logic now only applies to month range grid. community-pr: https://github.com/odoo/odoo/pull/226975 opw-5078200 Forward-Port-Of: odoo/enterprise#94593
When a website is created with only the Events option selected, Ecommerce will no longer be installed automatically. This keeps the setup focused on the selected business need and avoids adding irrelevant sales features.
Original PR description
Steps to reproduce: 1. Install website module 2. Select events in configurator 3. Build website. => Ecommerce is installed, which should not as it does not make sense with only the events. After this commit: - Ecommerce will no longer be installed when the events is configured. task-4922600 Forward-Port-Of: odoo/odoo#221527
The website editor no longer shows the Countries Filter option on the Partners page, where it had no effect. This prevents confusion for website editors by keeping customer-page settings visible only where they apply.
Original PR description
Scenario: - install website_customer and website_crm_partner_assign - go to /partners - in edit mode, disable the option "Countries Filter" Result: nothing happen Cause: there is no filter options on /partners page, but the options of /customers page are targetting class o_wcrm_filters_top that is common to both page, so they are shown on /partners incorrectly. Fix in stable: change the selector to only show options on /customers. Fix in master: in website_customer, change the o_wcrm_filters_top class to o_wc_filters_top class. opw-5102381 Forward-Port-Of: odoo/odoo#228575
UrbanPiper POS orders now apply the right taxes when a point of sale belongs to a branch and the tax is defined on the parent company. This prevents under-taxed orders and also supports split taxes such as GST components.
Original PR description
Steps to reproduce: --- - Install `pos_urban_piper`. - Create a branch under *Main Company*. - Switch to the new branch. - Create a POS config in this branch and set up UrbanPiper. - Sync "Apple Pie". - Place an order with "Apple Pie". Issue: --- - The 15% tax defined on Apple Pie is not applied on the orderline. Cause: --- - While creating the order line, the tax company was compared directly with the POS config’s company. In this case, the tax belongs to the parent company, while the POS config belongs to a child company. Fix: --- - Compare the `root_id` of both companies instead of the direct company ID to ensure taxes are applied correctly in multi-branch setups. - Additionally, handled the case where a main tax has sub-taxes (e.g., 5% GST split into 2.5% SGST and 2.5% CGST). In such cases, we now fetch the tax type from the sub-taxes instead of the main tax. Task-5050682 Forward-Port-Of: odoo/enterprise#93467
Point of Sale loyalty rewards now only grant points when an order meets the program’s item quantity rules. This prevents customers from incorrectly earning points or losing too many points when redeeming a free product.
Original PR description
Loyalty points were not being awarded correctly for some orders. The system granted points even when the minimum required quantity of items was not reached. In some cases, it also added negative…
Loyalty points were not being awarded correctly for some orders. The system granted points even when the minimum required quantity of items was not reached. In some cases, it also added negative loyalty points, which led to an excessive deduction for the customer —sometimes just for claiming a single free product. > Setup of the Loyalty Program (Discount & Loyalty): Program Type : Loyalty Card Rule : minimum 5 items => 10 Loyalty Points per $ Reward : Free product (Simple Pen) => in exchange of 5 Loyalty Points Steps to reproduce: ------------------- * Open the pos Shop * Select a customer with loyalty points * Add a Simple Pen * Click on * Reward > Free Product - Loyalty Program > Observation: Customer shouldn't 'win' points here New Total is mathematically correct but not logic Why the fix: ------------ We need to verify that the order is eligible to generate reward points based on the configured rules, before adding the won points. opw-4914774 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230166 Forward-Port-Of: odoo/odoo#221570
Website visitors and editors can now keep multiple selected tags when refreshing, opening the editor, or using search on blog and eLearning pages. This prevents filters from unexpectedly resetting and makes browsing tagged content more reliable.
Original PR description
Before the change in the blog/slides pages of a website every tag but one disappears when opening the editor or when the search bar is used. Steps to reproduce: - Log in Odoo with a user that can access the website editor Open the Website - Install the blog app if it is not already present - Open the blog app - Click on two or more tags to add them to the filter Open the Website editor or use the search bar - Every tag but one will be removed After the change all the tags will be kept when opening the editor or using the searchbar. task-4216129 Fixes #164577 Forward-Port-Of: odoo/odoo#226898
This fix prevents an error during module uninstallation that could leave database structures only partially removed. It helps ensure related apps such as Resource and Worksheet can be uninstalled and reinstalled cleanly without causing setup issues.
Original PR description
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks…
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks when uninstalling module `worksheet`:
```
ir.model.data._module_data_uninstall():
... records are deleted ...
ir.model.fields.unlink():
drop column of corresponding fields
delete ir.model.field records
ir.model.unlink():
drop table of corresponding models
ir.model._unlink_if_uninstalling():
self.env['worksheet.template'].search([('model_id', ...)]).unlink()
delete ir.model records
```
The call to `ir.model.unlink()` crashes when searching for worksheet templates, since column `model_id` has been dropped already. This makes the transaction fail, and it is rolled back to a savepoint just before the call to `ir.model.unlink()`. In other words, the uninstallation manages to drop most of the columns that must go, but fails to drop all the tables that must go. And the uninstallation proceeds anyway...
Now consider uninstalling module `resource`. That module defines model `resource.calendar` with required field `name`, and also defines a record in that model (a default calendar). When the module is uninstalled, module `worksheet` is also uninstalled (because it depends on `resource`), and so the situation above happens. Consequently, most of the columns of table `resource_calendar` are dropped, but the table is not. If we reinstall module `resource` after that, the ORM re-creates column `name` (which is `NULL` on the default calendar at least), but fails to add the `NOT NULL` constraint on that column.
The fix consists in avoiding the `search()` above in the ondelete method if the column `model_id` does not exist anymore.
Forward-Port-Of: odoo/enterprise#96845SEPA payment files will now mark payments as high priority only for Belgian companies. This helps companies in other countries avoid unnecessary bank fees while preserving the required behavior for Belgium.
Original PR description
Having priority set as HIGH for SEPA payments can induce extra fees (ex. in CH). This commit only sets the priority to HIGH for BE companies. task-4874217 Forward-Port-Of: odoo/enterprise#96869 Forward-Port-Of: odoo/enterprise#95420
This fix makes Odoo remember where users were on a page when they return to kanban, pivot, and mobile list views. It improves navigation continuity, especially when switching views or using breadcrumbs, so users do not need to manually find their previous position again.
Original PR description
When coming back to a view using the breadcrumb or with the view switcher, we want to restore the local state of the view as it was when we left it, in particular the scroll position. This is handled…
When coming back to a view using the breadcrumb or with the view switcher, we want to restore the local state of the view as it was when we left it, in particular the scroll position. This is handled by the `useSetupAction` hook, for all views (except for the list as the scrolling container is custom, because of the fixed table header). However, since [1], it was no longer working in kanban, pivot and list (mobile only). This was due to the fact that those views are now "lazy", i.e. they are rendered directly, without the data, such that the control panel is available asap. As a consequence, when `onMounted` is called (i.e. when the hook attempts to restore the scroll position), there's no scrollable content yet. This commit fixes the issue by allowing the controllers to restore the scroll position themselves, when their content is ready. In addition, a custom treatment was necessary for the kanban view, in mobile *and* if grouped, as each column has its own vertical scrollbar. [1] https://github.com/odoo/odoo/pull/205129 task~5086324 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
This fix updates test setup data so products are treated as properly configured instead of missing required supply details. It prevents false test failures caused by artificially extended lead times, helping keep manufacturing planning and rental workflows reliable.
Original PR description
This PR addresses the issue where tests were failing due to unconfigured products (no vendor/ no BoM). Now unconfigured products' lead_time is incremented by 365 due to this PR: https://github.com/odoo/odoo/pull/216293 Before this fix: Products have `buy` route by default and no vendor, so they are considered unconfigured products and lead time is incremented by 365, and tests fail as any lead time refers to a date earlier than today would only affect the first period in the MPS which is not intended in the tests. After this fix: Products have `manufacture` route and there is BoM, so they are considered configured products and lead time is calculated normally from BoM which is 0. Task-4779057 Forward-Port-Of: odoo/enterprise#88766
Products missing key setup, such as a bill of materials or vendor, will now appear on the replenishment report much earlier instead of only on the delivery date. This gives teams more time to notice configuration gaps and fix them before they affect purchasing, manufacturing, or deliveries.
Original PR description
Before this commit, RR for unconfigured products (no BoM/ no vendor), was not created until the same day of the delivery date (lead_time=0). Now, RR for unconfigured products is created considering the lead_time is incremented by 365 days. Note that this commit reverts the effect of the commit: https://github.com/odoo/odoo/commit/40d0bc0df0dc09f5138aa747cbbc715ae77f104c It's functionally decided to make the total lead_days for products with no bom to be 365 days without adding the security_lead_days. It's meant just to warn the user on the RR dashboard that the product needing replenishment is not configured, no matter to the security_lead_days in this case. Task-4779057 Forward-Port-Of: odoo/odoo#216293
Fixes an issue where returning a non-rental item included in a rental order could leave the sale order showing an incorrect delivered quantity. This helps sales and warehouse teams keep delivery status and invoicing information accurate after returns.
Original PR description
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a…
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a rental order with (in that order!): - A rental product - A non-rental product - Confirm the rental order. - Open the related sale order. - Go to the delivery and validate it. - Return the delivery and validate the return. - Observe that the delivered quantity in the sale order is incorrect. **Cause**: The [_get_outgoing_incoming_moves](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/sale_stock/models/sale_order_line.py#L200C17-L200C85) method fails to detect incoming moves when the destination location has `usage='internal'` (as in rental flows), instead of `customer` (see [_is_outgoing()](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/stock/models/stock_location.py#L464)). This causes the delivery quantity not to be decremented on return. **Solution**: Relax `_is_incoming()` logic to consider moves as incoming if they come from a rental and go to an internal location. opw-4894358 Forward-Port-Of: odoo/odoo#222093
Returning non-rental items from a rental order now updates delivered quantities correctly. Rental item returns are also handled so they do not incorrectly reduce delivered quantities, improving order accuracy and reducing manual corrections.
Original PR description
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a…
**Issue**: Returning a non-rental product in a rental order does not correctly update the delivered quantity. **Steps to reproduce**: - Enable rental transfers via Settings > Rental. - Create a rental order with (in that order!): - A rental product - A non-rental product - Confirm the rental order. - Open the related sale order. - Go to the delivery and validate it. - Return the delivery and validate the return. - Observe that the delivered quantity in the sale order is incorrect. **Cause**: The [_get_outgoing_incoming_moves](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/sale_stock/models/sale_order_line.py#L200C17-L200C85) method fails to detect incoming moves when the destination location has `usage='internal'` (as in rental flows), instead of `customer` (see [_is_outgoing()](https://github.com/odoo/odoo/blob/ea6776f095d556e3429d2b847a66f78f2e866380/addons/stock/models/stock_location.py#L464)). This causes the delivery quantity not to be decremented on return. **Solution**: Relax `_is_incoming()` logic to consider moves as incoming if they come from a rental and go to an internal location. **Additional fix**: [This commit](https://github.com/odoo/odoo/commit/886b3ea5d463722413f3cae14d4be1ad5fc88ab9) changed the default of `to_refund` to `True`. Combined with [this change](https://github.com/odoo-dev/odoo/blob/1e7ffa60dc1495243d8d99ac03c1701fbd056fe1/addons/sale_stock/models/sale_order_line.py#L330C13-L330C94), returning a rental product is treated as an incoming move, which incorrectly decreases the delivered quantity. To fix this, rental products are never marked as refundable when the SO is created: we adapt the procurement value to set `to_refund=False` on rental return moves. This ensures the delivered quantity is correctly updated for rental products, while non-rental products in a rental context remain refundable. opw-4894358 Forward-Port-Of: https://github.com/odoo/enterprise/pull/91825
This update corrects an automated test so it no longer depends on Belgian localization behavior that may not be present in smaller app builds. It helps keep Peppol-related quality checks reliable without changing customer-facing features.
Original PR description
This commits fixes test we previously added [1]. In Belgium, the Company Registry (0208) and the VAT number (9925) can be computed from each other (`0208:0400000000` <-> `9925:BE0400000000`). [This compute](https://github.com/odoo/odoo/blob/0d8aadb2db7f10d439e10f222ec0ab6dcfab3672/addons/l10n_be/models/res_partner.py#L13) is actually only available in l10n_be, while the test rely on it to deduce the expected EAS, and therefore fails on single Apps builds. [1]: https://github.com/odoo/odoo/pull/230880 [runbot-error-233343](https://runbot.odoo.com/odoo/runbot.build.error/233343)
This fix prevents the Colombian online checkout address form from getting stuck when shoppers select certain tax obligation options. Customers can now save their address and continue to delivery as expected, reducing checkout interruptions for Colombian websites.
Original PR description
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and…
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and there is an “expected singleton” traceback in the logs. This is because in the method `_parse_form_data` in `l10n_co_website_sale`, the obligation type field on `form_data` is set to be a list of “type ids” which leads to an error when `convert_to_cache` is called as the browse function in this attempts to convert the list to a tuple of single characters. For example, if the list is ["10"], it gets converted to ("1","0") hence leading to the expected singleton traceback.
Purpose: Instead of passing a form list to form_data,we pass the record set which will correctly set the values in the address, much like how `default_obligations_ids` is also currently set. After this correction, the website address screen will save the address properly and redirect to the delivery screen for further actions.
Steps to Reproduce on Runbot:
1. Create a Colombian company, make sure l10n_co is installed
2. Set the company on the website to this company
3. Ensure that there is a record in the table `l10n_co_edi_obligation_type_ids` with id > 9. Create one if it does not exist.
4. Open the /shop page in incognito mode as a public user.
5. Add a product, go to the checkout page, proceed to the address page.
6. Enter all the information including the Identification Number (e.g. 623.456.789-1). Choose “NIT” in identification type and select the type code from step 3 in the dropdown for obligation type. Choose country “Colombia” along with a state and city
7. Click on "Continue checkout". The page gets stuck in a loading state
forever.
opw-4776301
Forward-Port-Of: odoo/enterprise#90862