Daily updates from Odoo
Wednesday, April 22, 2026
46 changes · saas-19.1
Enhancements to existing features
This change improves how the system reports failures when a connection drops during a wait. Instead of showing a confusing cancellation message, it now surfaces the real underlying problem so support teams can identify the cause more quickly.
Original PR description
This case induces confusion in the ranks: when the WS connection fails, the result of the run is set to failure then every outstanding response is cancelled. For `_wait_ready` specifically, because…
This case induces confusion in the ranks: when the WS connection fails, the result of the run is set to failure then every outstanding response is cancelled. For `_wait_ready` specifically, because it's a blocking wait on a request it yield a confusing result as the run fails with `CancelledError` and the actual cause (the WS was closed) is lost. One option would be to `set_exception` on the waiting responses, but I feel like this could create other confusing knock-on effects e.g. more evented waits which currently get ignored might start raising exceptions (although that seems unlikely as callbacks apparently do get called on cancel), and since issues with cancelling only seem to appear in `_wait_ready` that seems like overkill. Instead have `_wait_ready` handle cancellation by first checking if the result is in error, and using that to raise the underlying error, otherwise retry (and ultimately timeout, probably). And while at it, before signaling a timeout check if the run is in failure and raise that immediately, just in case. https://runbot.odoo.com/odoo/error/233738 Forward-Port-Of: odoo/odoo#260324
The website’s video snippet preview now uses a lightweight SVG image instead of an embedded video. This reduces ongoing maintenance and makes the preview more reliable over time.
Original PR description
Prior to this PR, the `s_video` inner snippet was using a video as placeholder, which implied maintenance to ensure the video is always available. To avoid maintenance and ensuring long term effectiveness, we replace this video with a `SVG` placeholder, similarly to what has been done for the `s_image`. task-5441285 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260042
The explanation for the Invoicing Switch Threshold has been clarified to better describe which entries are ignored. This helps users understand that all entries created by Invoicing before the threshold date are excluded, avoiding confusion and incorrect expectations.
Original PR description
The previous "Invoicing Switch Threshold" explanation was misleading as it said only invoices prior to the threshold date is not taken into account. The explanation is updated to state that all entries created by Invoicing before the threshold date will be ignored. task-5940144 Forward-Port-Of: odoo/enterprise#113635
After databases are synchronized from Odoo.com, the system now tries to create a local API key for each database that does not already have one. This reduces an extra validation step against the global key, which makes database access faster and can save about half a second per database in some cases.
Original PR description
Before this commit, databases fetched from Odoo's SaaS were contacted using the global API key, which is more costly than using a key local to each database. Avoiding the call from the server to Odoo to check the foreign API key can spare about 500ms on each database where this key is not in the LRU. With this commit, after the synchronization with Odoo.com, we try to generate an API key on each database that doesn't have one yet. To do so, it relies on the API introduced by odoo/odoo#246118. Forward-Port-Of: odoo/enterprise#106372
The Moves Analysis report now shows the date of each stock move directly in the list view. This makes the report easier to read and removes the need to switch to debug mode to see this basic information.
Original PR description
The date of the move is a basic and important information. Show it on the 'Moves Analysis' report list view, previously was only displayed in debug mode. task-5380628 Forward-Port-Of: odoo/odoo#254999
Resolved issues and error corrections
When users create a vendor bill by auto-completing from a previous bill, the Intrastat transaction information is now kept on the copied lines. This avoids missing reporting data and helps ensure bills are prepared correctly for EU-related transactions.
Original PR description
Currently, Intrastat transaction values are not set when creating a vendor bill using the `Auto-complete` feature based on a previously created vendor bill for an `EU customer`. **Steps to…
Currently, Intrastat transaction values are not set when creating a vendor bill using the `Auto-complete` feature based on a previously created vendor bill for an `EU customer`. **Steps to reproduce:** - Install `account_intrastat` and `l10n_de` modules and switch to a `DE company`. - Create a vendor bill for an `EU partner`, add a product, and set an `Intrastat` (enable from the optional column if needed). - `Confirm` the bill and note its number. - Create a new vendor bill for the `same partner`. - Use the `Auto-complete` feature by selecting the previous bill. - Check the invoice lines. **Observation:** The `Intrastat` is missing from the generated invoice lines. **Root Cause:** - On using `Auto-Complete`, `_onchange_invoice_vendor_bill` at [1] copies invoice lines using `copy_data()`. - However, in `account_intrastat`, `copy_data()` at [2] removes `intrastat_transaction_id`. **Fix:** This commit ensures that `Intrastat` is properly set when creating a vendor bill using the auto-complete feature based on a previously created vendor bill for an EU customer. [1]: https://github.com/odoo/odoo/blob/07b72963c665f2fe5b741b8815f2351129a2271c/addons/account/models/account_move.py#L1808-L1820 [2]: https://github.com/odoo/enterprise/blob/4da85b58a28837379e4839327ea914bd6aa70bf9/account_intrastat/models/account_move.py#L77-L83 opw-5936869 Forward-Port-Of: odoo/enterprise#114520 Forward-Port-Of: odoo/enterprise#112857
This fix prevents an error when exporting the General Ledger in Peruvian companies if draft invoice entries are included. Users can now complete the export successfully without the report failing on unfinished documents.
Original PR description
**Steps to reproduce:** - Install the `l10n_pe_reports_lib` module and switch to a `PE company`. - Create a draft invoice. - Navigate to Reporting > General Ledger. - Click the gear icon and select `Inventory and Balance`. **Error:** AttributeError: 'NoneType' object has no attribute 'replace' **Root Cause:** For draft entries, `move_name` is `None`, and calling `.replace()` on it causes an error at [1]. **Fix:** This commit prevents errors and ensures users can export the general ledger even when draft entries are included. [1]: https://github.com/odoo/enterprise/blob/5babcb5cb951e0e7beebdbef0781a20a7a19c319/l10n_pe_reports_lib/models/account_general_ledger.py#L168 opw-6104117 Forward-Port-Of: odoo/enterprise#113405
The invoice currency rate date picker now lets users select today’s date correctly. This fixes a frustrating issue where choosing today did nothing, so the system now applies today’s exchange rate, or the latest available rate if today’s is missing.
Original PR description
On an invoice, using the date picker to choose the currency rate did not allow picking today's date. Steps to reproduce: - Activate a currency - Add currency rate for today, yesterday and tomorrow - Create a new invoice - Select the newly activated currency - Pick yesterday's date - Pick today's date Current behavior: picking today's date close the date picker without doing anything Expected behavior: picking today's date close the date picker and apply today's currency rate (or latest if today's doesn't exist) Cause: The date picker was opened with today's date selected, preventing selecting it again. Opening the date picker with the right date selected isn't possible as we don't save the currency rate date. It would require doing a reverse search among the currency rate date which might be wrong as the currency rate can be customized. opw-6046169 Forward-Port-Of: odoo/odoo#258368
This fix ensures approval request printouts are translated even when no contact is linked to the request. If a contact language is unavailable, the system now falls back to the request owner's language, or to the default language when needed.
Original PR description
Steps to reproduce: ------------------ 1. Install Approvals. 2. Select an approval type from Approvals > Configuration and ensure the 'Contact' field is not required. 3. Install a second language (e.g., Arabic) and switch the user's language. 4. Create a new approval request with this approval type and set user as the request owner. 5. Try to print the approval request. Current behavior: ----------------- The report is only translated when partner is present because it translates using `partner_id.lang`. Since the partner is not required in all cases, `lang` can evaluate to False when it is missing, causing the report to bypass translations. Expected behavior: ------------------ The report should fall back to the request owner's language or the system's default language if the partner is not available. opw-6010222 Forward-Port-Of: odoo/enterprise#112476
This change makes the timeout for the Mindicador currency rate service configurable instead of fixed. It helps avoid missed daily exchange-rate updates when the external service is slow, reducing gaps in stored rates and keeping currency data more reliable.
Original PR description
The mindicador.cl provider had a hardcoded 30s timeout on its HTTP requests. The mindicador.cl service is sometimes slow around rate publication time, causing read timeouts that make the cron silently skip currency rate creation for the day due to HTTP Timeouts, leaving permanent gaps in res.currency.rate. Make the timeout configurable through the `mindicador_api_timeout` system parameter (defaults to the previous 30s). opw-6126027 Forward-Port-Of: odoo/enterprise#114153
This update prevents an access error that could appear when choosing a vendor or adjusting replenishment settings in a multi-company setup. It makes supplier selection behave correctly even when products have vendors linked to more than one company, so users can work without unexpected interruptions.
Original PR description
Issue before this commit: ------------------------------------------ In replenishment (multi-company setup), a 'read' access error occurs while setting the supplier, changing the replenishment unit,…
Issue before this commit: ------------------------------------------ In replenishment (multi-company setup), a 'read' access error occurs while setting the supplier, changing the replenishment unit, or changing the min/max when there are suppliers across multiple companies. Steps to reproduce: ------------------------------------------ 1. Install purchase_stock. 2. Create a storable product. 3. Add one vendor for company A and one vendor for company B. 4. Make sure that only company A is active. 5. Create an orderpoint for company A (min/max = 0) and set the route to 'Buy'. 6. Try to set the vendor. Notice that an access error occurs. Cause of the issue: ------------------------------------------ This issue occurs because the `seller_ids` cache gets polluted with suppliers from multiple companies. As a result, when `self.seller_ids` is accessed [1], it returns vendors from both active and non-active companies, ignoring the current company context. [1] https://github.com/odoo/odoo/blob/47deb9f13627a26d6a3179399bd965f639fde436/addons/product/models/product_product.py#L1016 Since users are not allowed to read records from non-active companies, this leads to a read access error when those supplier records are accessed. * Cause of the cache pollution: The cache gets polluted with records from another company because `product.seller_ids` [2] is accessed in a `sudo()` environment. This happens due to the `qty_to_order_computed` field, which is stored and computed. By default, stored computed fields use `compute_sudo=True`, causing the computation to run in a `sudo()` environment and cache cross-company sellers. [2] https://github.com/odoo/odoo/blob/d11b56f9272be39169d382007d19d63739617a8a/addons/purchase_stock/models/stock_rule.py#L169 Solution: ------------------------------------------ Filter the sellers in sudo mode as well, since the `seller_ids` cache will otherwise always be polluted due to the sudo environment. opw-6034990 Forward-Port-Of: odoo/odoo#259403
Fixed an issue that prevented portal users on mobile devices from uploading files into shared document folders. The upload action now stays active long enough for the phone’s file picker to complete, so selected files are uploaded correctly.
Original PR description
Steps to reproduce: 1. Install `documents` 2. Create a portal user and share a document folder with edit access 3. Log in as the portal user on a mobile device 4. Try to upload a document inside the…
Steps to reproduce:
1. Install `documents`
2. Create a portal user and share a document folder with edit access
3. Log in as the portal user on a mobile device
4. Try to upload a document inside the shared folder
Issue:
- After selecting a file from the file picker, the document is not uploaded.
Cause:
- On mobile in the portal flow, Upload is triggered from a nested dropdown (inside New) inside the adaptive control-panel dropdown (bottom sheet). By default, DropdownItem uses closingMode="all", so tapping Upload closes parent dropdowns immediately. That unmounts the hidden <input type="file"> before the OS file picker returns. When the user comes back, the input no longer exists, so change never fires and upload does not start.
- Admin/internal users do not hit the same nested adaptive-dropdown path in this view
Solution:
- Set closingMode="'none'" on the Upload DropdownItem so the menu stays mounted while the native picker is open. After a file is selected and onFileInputChange starts upload, close the bottom sheet programmatically with: `window.dispatchEvent(new Event("popstate"))`
opw-5937105
Forward-Port-Of: odoo/enterprise#108486This fixes the displayed name of return periods so the starting year now matches the actual calendar year. Previously, some dates could be shown as the prior year because the system used the wrong year format, which could confuse users reviewing reports.
Original PR description
Steps to reproduce: - Create a return from Jan 2023 to April 2023 -> the dates displayed in the name will be Jan 2022 - Apr 2023 The display is incorrect because we used the wrong date format, and therefore switch from using YYYY to yyyy as the first one is the ISO standard year and the second the calendar year. They might differ on the result here because 01 Jan 2023 falls on a Sunday, but ISO week starts on Monday, so it took the previous year (2022) Forward-Port-Of: odoo/enterprise#114428
The W-2 report can now generate a CSV file even when the End Date is left blank. If no end date is provided, the system uses the current year for the file name instead of failing with an error.
Original PR description
Currently, an error occurs when user tries to create a csv for w2 form with no end date defined. Steps to replicate: - Install `l10n_us_hr_payroll`. - Open Payroll > Reporting > W2 Report. - Click…
Currently, an error occurs when user tries to create a csv for w2 form with no end date defined.
Steps to replicate:
- Install `l10n_us_hr_payroll`.
- Open Payroll > Reporting > W2 Report.
- Click `New` > Remove value from `End Date` and click Generate.
Error:
```
File '/home/odoo/odoo19/enterprise/l10n_us_hr_payroll/models/l10n_us_w2.py', line 249, in action_generate_csv
self.csv_filename = f'form_w2_{self.date_end.year or date.today().year}.csv'
^^^^^^^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute 'year'
```
Cause:
- As the user did not give any value for `End Date`, False was passed and when the execution flow reached [here] `self.end_date` is False and attempting to access `self.end_date.year` results in this error.
Solution:
- If we do not receive the `self.end_date` while generating the CSV, we will use the current year to generate the CSV file name.
[here]: https://github.com/odoo/enterprise/blob/01be8d6e9384bcb340559847d529b4887e073519/l10n_us_hr_payroll/models/l10n_us_w2.py#L248
No ID
Forward-Port-Of: odoo/enterprise#114363
Forward-Port-Of: odoo/enterprise#113408This fix makes sure that when a work schedule’s time period is changed, the related duration is recalculated automatically. It prevents errors in attendance views and keeps employee schedules displaying correctly.
Original PR description
Since #217895, `duration_hours` is now stored and needs to be recomputed when we change the attendance's `day_period` from lunch to morning/afternoon/full_day otherwise we will run into division by 0 in `_get_attendance_intervals_days_data`. ### Steps to reproduce 1. Change the day period of one of the working hours of a working schedule from Lunch to Morning. 2. Open the attendance overview including the attendances of an employee that has the working schedule from step 1. opw-6129881 Forward-Port-Of: odoo/odoo#259904
This change updates the Windows packaging setup so it includes optional dependencies required for a smoother installation and runtime experience. It helps avoid missing-component issues for Windows users and makes the packaged product more reliable.
Original PR description
Forward-Port-Of: odoo/odoo#258320 Forward-Port-Of: odoo/odoo#258128
The Belgian 0% S tax setup has been updated with the correct exemption code and exemption reason. This helps ensure invoices and tax reports use the proper official classification, reducing the risk of reporting errors.
Original PR description
The tax 0% S had a wrong tax exemption code and tax exemption reason. This commit corrects it. Task-6127195 Forward-Port-Of: odoo/odoo#259639
This update ensures product costs are calculated correctly when some stock is owned by a supplier or other external party. It prevents company-owned inventory from being undervalued in stock views and valuation screens, helping finance and operations see accurate stock values.
Original PR description
edit : the issue was fixed by https://github.com/odoo/odoo/pull/257103 So this commit only contains these use cases tests **Steps to reproduce:** - enable consignement setting - create a tracked avco…
edit : the issue was fixed by https://github.com/odoo/odoo/pull/257103 So this commit only contains these use cases tests **Steps to reproduce:** - enable consignement setting - create a tracked avco product with a cost of 10 - click on the quantities smart button and then "update quantity" to open the quants view - create one line with a quantity of 1 and no owner - create one line with a quantity of 1 and an owner outside the company **Current behavior:** problem A: open the 'stock' view and look for your product, the unit cost is 5 problem B: navigate back to the quants view of the product, unhide the value column, the value is 5 for the non consigned quant **Expected behavior:** problem A: the unit cost should be 10 (because consigned product shouldn't be taken into account when computing the unit cost) problem B: the non consigned quant value should be 10 for the same reason **Cause of the issue:** problem A: Inside _compute_value(), to compute total_value_by_company_id, we use _with_valuation_context() https://github.com/odoo/odoo/blob/6c107cd70e2228d3428e53cf8095aba17f678d8a/addons/stock_account/models/product.py#L196-L203 which excludes consigned products https://github.com/odoo/odoo/blob/6c107cd70e2228d3428e53cf8095aba17f678d8a/addons/stock_account/models/product.py#L362-L364 So when we iterate through 'products' and fetch qty_available for our product the value is going to be 1. But when computing avg_cost at the end of the method, we iterate through 'self', so we don't have this context anymore and the value of qty_available is 2. https://github.com/odoo/odoo/blob/6c107cd70e2228d3428e53cf8095aba17f678d8a/addons/stock_account/models/product.py#L271-L273 That's because qty_available is computed with _compute_quantities() which depends on context (including owner_id) https://github.com/odoo/odoo/blob/53f7d1dd2f972921ba91f6083a49f50749a3f503/addons/stock/models/product.py#L148-L152 problem B: when computing the value of the quant, there is no context specifying that the consigned quantities should be excluded https://github.com/odoo/odoo/blob/53f7d1dd2f972921ba91f6083a49f50749a3f503/addons/stock_account/models/stock_quant.py#L61-L62 opw-6049413 Forward-Port-Of: odoo/odoo#257013
Updating an attendance record will no longer reset overtime entries that were already approved in the same week. This keeps manager approvals intact unless the overtime calculation itself changes, reducing repeated review work and confusion.
Original PR description
Creating or updating an attendance record resets previously approved overtime entries in the same week back to the 'to_approve' status. ### **Steps to reproduce:** 1) Install Attendance with demo…
Creating or updating an attendance record resets previously approved overtime entries in the same week back to the 'to_approve' status. ### **Steps to reproduce:** 1) Install Attendance with demo data. 2) Set 'Extra Hours Validation' to 'Approved by Manager' in settings. 3) Ensure an overtime rule is set for the Admin user. 4) Create an attendance for Admin with some overtime. 5) Navigate to management and approve overtime. 6) Create another attendance with overtime for Admin in the same week. 7) Navigate back to management. ### **Observed Behavior:** Previously approved overtime reappears in the list, requiring approval again. ### **Expected Behavior:** Previous overtime should remain in the 'approved' status, provided its calculated duration has not changed. ### **Root Cause:** When an attendance is added or modified, the [_get_overtimes_to_update_domain](https://github.com/odoo/odoo/blob/3891dd471d64629634644c0b022a171bbaa65b49/addons/hr_attendance/models/hr_attendance.py#L268-L286) method evaluates the entire week regardless of the ruleset. This means any daily attendance update wipes and recreates the entire week. ### **Fix:** Check the ruleset of the employee. If no rule has `quantity_period` set to **'week'**, restrict the domain to the specific days of the attendances being modified, rather than the entire week. **opw-6054497** Forward-Port-Of: odoo/odoo#256281
This change corrects how self-billed invoices are matched when more than one company is registered on Peppol. It ensures each incoming invoice is assigned to the right company, preventing accounting entries from being created under the wrong legal entity.
Original PR description
Currently, if a database has multiple companies registered on Peppol, receiving a self-billed invoice may assign it to the wrong company. The system was searching the journal using a domain that included all companies (in self), instead of filtering by the correct current company. Steps to reproduce: - Create a database with 2 companies, both on Peppol - Receive a self-billed invoice from a random other company on Peppol - The received invoice will potentially be assigned to the wrong company This is only a test forward-port of #257380 opw-6045669 Forward-Port-Of: odoo/odoo#259524 Forward-Port-Of: odoo/odoo#259072
When someone types an email address in the editor, it is now automatically turned into a clickable email link as soon as they press space. This makes it easier to create email links correctly and improves the editing experience.
Original PR description
Before this commit: when typing an email address, it's not converted to a mailto link after spacing. After this commit: the mailto link is created after spacing. task- 6053993 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258736 Forward-Port-Of: odoo/odoo#257497
Users without stock permissions can now copy Helpdesk tickets that include product information without triggering an access error. This avoids a blocking issue and makes ticket handling smoother for support teams with limited access rights.
Original PR description
Steps to reproduce: - Install helpdesk_sale_timesheet. - Create a Helpdesk Ticket and set its sale_line_id. - Log in as a user without stock.group_stock_user access. - Try to duplicate the ticket. Issue: Duplicating a ticket raises an AccessError because the user lacks stock rights required when copying the product_id. Fix: Set `product_id` to False during duplication for non-stock users. Reference: https://github.com/odoo/enterprise/pull/9100 task-5356318 Forward-Port-Of: odoo/enterprise#114266 Forward-Port-Of: odoo/enterprise#101338
This change fixes an unstable automated test in the HTML editor so it no longer fails randomly on slower systems. It does not change customer-facing behavior, but it makes the test suite more dependable and reduces false alarms during validation.
Original PR description
Waiting for a full animation frame is too dangerous. In the general case, an animation frame happens every 16ms, in which case the power buttons haven't been updated yet since they have a debouncing timeout of 30ms. However, when the runbot is slow, more than 30ms may very well have elapsed between two animation frames. When that is the case, the power buttons are displayed and the test fails. This commit changes the forced awaiting of an animation frame to a waiting pased on the time passed. In the general case, an animation frame will have happened in 20ms, so the test will still catch a regression. When the runbot is slow however, more time might have passed, but not necessarily an animation frame, so the power buttons should still be invisible, making this test more reliable. runbot-242466 Forward-Port-Of: odoo/odoo#259854 Forward-Port-Of: odoo/odoo#259654
Imported XML files are now kept attached in a safer way so they can still be accessed by related invoice flows. This prevents access errors when opening bills created from email aliases or manual imports, especially for Mexican electronic invoicing cases.
Original PR description
When importing files (manually or from email alias), we unattach the xml files, it can lead to access error in some flows like with l10n_mx_edi Steps to reproduce the flow that triggered the bug: - Install l10n_mx_edi and select MX company - Create an email alias for purchase journal - Receive email with xml file - Create a user with 'group_user' role, 'Administrator' accounting access rights - Login with this user and open the created bill -> Access Error This is because we unattach xml attachmentss when importing them, by setting `res_id` to 0 and `res_model` to False. The mx edi flow adds the `l10n_mx_edi_cfdi_attachment_id` via `_get_mail_thread_data_attachments` which lead to an access error during the `fetch` method opw-5953578 Forward-Port-Of: odoo/odoo#260127 Forward-Port-Of: odoo/odoo#259095
This change corrects how child contact names are shown again, restoring the expected display for related contacts. It helps ensure invoices and customer records use the right names, reducing confusion in day-to-day business operations.
Original PR description
This reverts commit 0ef4c1d06fdf999ad5cdad696069aec8f2f943c5. opw-5900567 Forward-Port-Of: odoo/odoo#260186 Forward-Port-Of: odoo/odoo#260065
This change prevents loyalty points from being rounded as if they were currency when the program is not money-based. As a result, point-based rewards will no longer be accidentally reduced to zero in currencies with large rounding steps, so customers can claim their rewards normally.
Original PR description
`_get_real_points_for_coupon` was unconditionally rounding points using `coupon.currency_id.round()`, which uses the currency's rounding factor as a precision unit. For point-based programs (e.g. 1 point per order), a currency with a large rounding factor (e.g. 10) would round 1 point down to 0, making all rewards unclaimable. Currency rounding is only semantically correct when points represent monetary amounts, which is the case when `reward_point_mode == 'money'` (gift_card, ewallet, and money-mode loyalty programs). For all other programs, points are dimensionless and should not be subject to currency precision rules. opw-6111622 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259660
This update automatically removes Timesheets assistant suggestions older than 30 days. It prevents unused data from piling up in the browser storage, helping keep the feature lightweight and reliable over time.
Original PR description
In the Timesheets assistant, we store the suggested events taken or dismissed by the user to avoid suggesting them again. However, there is no mechanism to remove them from the localstorage, so it currently grows infinitely. With this PR, we now delete events older than 30 days, to avoid filling the localstorage with useless data. Task-6131640
This update prevents an error that could appear when using the Project app on mobile and adding a dependency in the “Blocked by” section. It ensures the page opens correctly, improving reliability for users working on tasks from their phone.
Original PR description
Steps to reproduce: - Install Project - Create a project and a task and enable task dependencies - In mobile view, go to the "Blocked by" tab and click "Add" Issue: A traceback occurs in the mobile view. Cause: In this pr https://github.com/odoo/odoo/pull/230738 parent_id was moved inside anchor element. Fix: Update the XPath to correctly replace the element containing parent_id. task-6009997
The attendance Gantt view now shows the expected hours correctly for employees with flexible working schedules. This prevents the hours bar from disappearing or showing the wrong value on longer date ranges, making planning and attendance tracking more reliable.
Original PR description
For employees having a `resource_calendar_id` with `flexible_hours`, the max hours displayed in the gantt view were incorrectly `days * hours_per_day`. This fixes it by taking the most relevant data between `days * hours_per_day`, `weeks * hours_per_week`, both, or nothing if the range is more than a month. The new calculation is `(weeks * hours_per_week) + min((days * hours_per_day), (hours_per_week))` task 5075953
This update fixes a typo in time-related text shown on website and mass mailing snippets, changing the wording from “am” to “pm” where appropriate. It helps ensure opening hours and scheduled times are displayed correctly and avoids confusion for customers.
Original PR description
am to pm
Point of Sale now converts product prices from the product’s own currency to the PoS currency, instead of incorrectly assuming all prices were in the company currency. This ensures customers are charged the correct amounts in multi-currency setups.
Original PR description
Before this commit, in a multi-currency environment, the company currency was used to convert the prices, while it was a wrong assumption that the product prices were in the company currency. The products have a currency_id field, and the price should be converted from that currency to the PoS config currency. opw-6065969 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257324
The website now correctly allows the quantity of combo products to be increased up to the available stock for their options. This fixes an issue where some combo products were incorrectly capped at 1, even when more units could be sold.
Original PR description
You cannot increase the quantity of a combo product that has options with Sell when Out-of-Stock disabled Steps to reproduce: 1. Install Inventory and eCommerce 2. Go to Website > eCommerce > Products and create a new product "Combo" 3. Set the Product Type to Combo, create and edit a Combo Choice "test" with two options "test 1" and "test 2". Both have Track Inventory enabled, 5 Quantity On Hand and Sell when Out-of-Stock disabled 4. Publish product "Combo" to the website 5. Click on smart button "Go to Website" to open the shop page of product "Combo" 6. Try to increase the quantity 7. The quantity is limited to 1 Solution: Always set the quantity input's maximum when `has_max_combo_quantity` is true Issue: We only set the quantity input's maximum if `allow_out_of_stock_order` is false This error was introduced in https://github.com/odoo/odoo/commit/0247538efe788a9ff9a4d58f64470325348a4eaa opw-6050876 Forward-Port-Of: odoo/odoo#257386
When a packaging barcode is scanned together with a lot and due date, the system now correctly keeps the due date instead of defaulting to today. This ensures expiration information is recorded accurately when products are handled by packaging rather than by product barcode alone.
Original PR description
Issue
-----
Scanning a GS1 barcode containing:
- packaging
- lot
- due date
disregards the due date when creating the new lot.
Steps to reproduce
-----
- Enable GS1 nomenclature & packagings
- Create a product
- barcode 23456789012344
- packaging with barcode 01234567890128
- some on hand quantity
- Create a delivery for a full packaging of the product
- Open the delivery in barcode
- Scan 02 01234567890128 15 270101 10 LOT1
- Validate
- Open the lot
> Expiration date is set to today
Cause
-----
The code expects the product be scanned, there is no logic to retrieve it from the packaging when missing.
-----
Ticket:
opw-6073489
Forward-Port-Of: odoo/enterprise#114327
Forward-Port-Of: odoo/enterprise#112490This update fixes a display issue in the bank reconciliation screen on small devices. After an entry is reconciled, the Reconcile button now disappears as expected, preventing users from clicking an action that would cause an error.
Original PR description
From saas-19.1, the reconciliation widget on small screens still shows the Reconcile button even after the entry is reconciled. Steps to reproduce: 1. Dashboard > Bank > Transactions. 2. Set a partner and reconcile an entry. 3. The Reconcile button is still visible on small screens. 4. Clicking it raises an error. The issue was caused by the button visibility still relying on `checked`, which has been replaced by `review_state`. This fix updates the condition so the buttons are correctly hidden for reconciled entries.
A bug in payroll could trigger an error while editing salary adjustments. The fix prevents the system from processing an empty start date, which avoids the traceback and makes the form behave normally.
Original PR description
This task guard against falsy date_start in _compute_estimated_end to avoid adding a relativedelta to False, fixing a traceback appearing during onchange. task-6139538
The system now only fills in supported document information when a partner is actually a valid Nemhandel participant. This avoids unnecessary processing and prevents test failures caused by running the lookup when no Nemhandel setup exists.
Original PR description
The method to fill the supported documents of a partner was called even if it was not a valid Nemhandel participant. This would cause some test to fail as the call was unexpectedly done on tests without any setup for it. Forward-Port-Of: odoo/odoo#259117 Forward-Port-Of: odoo/odoo#258704
This update corrects how roles are tagged in the full message composer. It ensures messages and links point to the right recipients, preventing missed notifications or incorrect addresses from being used.
Original PR description
There is an issue when tagging a role using the full composer: 1. Emails are sent to the wrong address or sometimes no address at all 2. The displayed URL is not correct This commit fixes the issue by correctly rendering the mention block for roles in the full composer, using the correct configuration. task-6139162 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260094
This fix ensures that a unit of measure set for one supplier and one specific product variant cannot accidentally be selected for other variants of the same product template. It helps avoid wrong purchase quantities and keeps supplier settings consistent across variants.
Original PR description
Make sure any UoM defined on a supplierinfo having a specific variant cannot be used by other variant of the same product template Task: 6042382 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#259213
This update ensures message text remains readable when a user clicks into the communication box, especially in dark website themes. It fixes the color styling so the text stays visible during typing in Helpdesk messages and similar customer-facing message areas.
Original PR description
# Setup Edit the theme of the website : in the Light & Dark section, set the first color to black. The main background color of the website should be black and the text should be in white. # How to…
# Setup Edit the theme of the website : in the Light & Dark section, set the first color to black. The main background color of the website should be black and the text should be in white. # How to reproduce - Install the Helpdesk app - Go to Website > Help - Submit a ticket (the ticket's information is not important) - Click the ticket link shown when the ticket is submitted - Start writing a message in the Communication History. # The problem As long as the text bubble is focused, the text is white even though the bubble is also white, making the text unreadable. Note : the same problem is present for product reviews in the eCommerce application. These text bubbles seems to be intended to stay white even in a dark main background color, so the text should be black : https://github.com/odoo/odoo/blob/6b21829159d3d16a0a0060e30814f9d969b44418/addons/mail/static/src/core/common/composer.scss#L103 # Cause The textarea (text bubble) has a the `.form-control` css class coming from bootstrap that applies `color: var(--bs-body-color)` : https://github.com/odoo/odoo/blob/6b21829159d3d16a0a0060e30814f9d969b44418/addons/web/static/lib/bootstrap/dist/css/bootstrap.css#L2115-L2131 In our case, it sets `color` to #FFF (I'm not 100% sure where this value is coming from since I did not find any instance where --bs-body-color or --body-color are ever set to that value). Anywyay, this value is overidden by `.o-discuss-text-body`: https://github.com/odoo/odoo/blob/6b21829159d3d16a0a0060e30814f9d969b44418/addons/mail/static/src/core/common/core.scss#L99-L101 But the value is overriden again when the textarea is focused by the `form-control:focus` css class that sets back the color to #FFF: https://github.com/odoo/odoo/blob/6b21829159d3d16a0a0060e30814f9d969b44418/addons/web/static/lib/bootstrap/dist/css/bootstrap.css#L2143-L2149 The issue was caused by this commit that changed the class used to define the color for the discuss messages : https://github.com/odoo/odoo/commit/3557de4232ebc307c8861379f6573d7b36cd8db6 Because `.o-discuss-text-body` is overriden by `form-control:focus` while `.text-body` is not. This is most probably due to the order in which the stylesheets are applied. # Proposed solution Add `, .o-discuss-text-body:focus` to make sure the rule is also applied when the text bubble is focused opw-6063961 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258142
This update fixes the number shown in the pager for grouped list views. When the system already knows the full record total, it now displays that true total instead of a capped placeholder, making counts more accurate for users.
Original PR description
When a pager is needed in a grouped list view and if the total number of record is greater than the `count_limit` (by default equal to 10000); opening the group or pressing the "Next" button will display the `count_limit` in the Pager.
This behavior can be optimized since the `web_read_group` call already computed the total count.
This commit allow the grouped list pager to display the total record count if it was already computed.
Steps to reproduce:
in a list view with 10 records, all in the same group for simplicity:
```xml
<list limit="2" count_limit="8">
<field name="foo"/>
</list>
```
- group the view by "foo" => The pager displays: `"1-2 / 10"`
- click on the 'next' button of the pager => The pager displays: `"3-4 / 8"`
8, the `count_limit` is shown instead of 10, the number of records in the group.
task-6053705
Forward-Port-Of: odoo/odoo#259858
Forward-Port-Of: odoo/odoo#259562When subcontracting resupply pickings are created through a stock-based routing rule, they will now correctly display the originating purchase order. This makes it easier for users to trace where a resupply came from and follow the process without having to search manually.
Original PR description
### Steps to reproduce: - In the settings enable: Subcontracting, Multi-Step Routes - Inventory > Configuration > Warehouse Management > Routes - Edit the 'Resupply Subcontractor on Order' route,…
### Steps to reproduce: - In the settings enable: Subcontracting, Multi-Step Routes - Inventory > Configuration > Warehouse Management > Routes - Edit the 'Resupply Subcontractor on Order' route, rules supply method to: Take from stock, if unavailable, trigger another rule (mtso) - Create a subcontracted bom For a product P with a component COMP - Create and confirm a PO for 1 unit of P with your subcontractor - Use the Resupply smart button to access the resupply picking #### > The resupply picking does not refer to the source PO ### Cause of the issue: The link is currently computed based on `move_dest_ids` which are only set for mto moves. However, moves created from mtso rules are `make_to_stock`. ### Fix: Since 19.0 2713876dbc70d3984e584a9037a2206dcda4e84a, we can rely on references to rebuild the link between the resupply picking and the source PO even in mtso. Note that this will also add the source PO link to each other picking of the reference. opw-6079680 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256689
This update fixes how the editor handles text inside inline code. It prevents editing tools from appearing in situations where they would not be useful, and ensures formatting actions and pasted content are treated properly when code and normal text are mixed.
Original PR description
### Purpose of this commit: - Prevent the powerbox and toolbar from opening when the selection is fully inside inline code. When the selection spans inline code and regular text, keep the toolbar visible but ensure formatting commands are applied only to the non-inline-code content. - Ensure that pasted external and editor HTML is converted to plain text when inserted inside inline code. task-5502939 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258781 Forward-Port-Of: odoo/odoo#250911
This update prevents the tax report from crashing when users compare it with one past period. It improves stability in reports that contain text-based values, so users can view comparisons without errors.
Original PR description
To reproduce: - Create a company in LU - Open the annual tax report for LU - Click on the comparison filter, compare with 1 period in the past ==> Traceback. This happens because that report contains a string value (an editable one, but it's not important here). Since there are only 2 comparison periods, we try creating the "%" column, comparing their amounts. The condition checking whether or not to display "N/A" was wrong, as it considered the values could only be int/float or None. Here, they are strings, so we don't enter that condition and crash when trying to evaluate float_is_zero on a string. Forward-Port-Of: odoo/enterprise#113330 Forward-Port-Of: odoo/enterprise#112619
Prices shown in Point of Sale now handle currency differences correctly when a pricelist is based on another pricelist in a different currency. This prevents surcharges and discounts from being calculated with the wrong amount, so customers see accurate prices in multi-currency setups.
Original PR description
Steps to reproduce: ------------------- 1. Set up a POS with a currency different from the company currency (e.g. company in USD, POS in SSP). 2. Create a USD pricelist with a surcharge rule (e.g.…
Steps to reproduce: ------------------- 1. Set up a POS with a currency different from the company currency (e.g. company in USD, POS in SSP). 2. Create a USD pricelist with a surcharge rule (e.g. +10 USD on list_price). 3. Create an SSP pricelist that references the USD pricelist as its base (base = "pricelist"), with an additional discount rule. 4. Assign the SSP pricelist to the POS and add a product. -> The displayed price ignores the currency conversion between the two pricelists: surcharges/discounts are applied as if both pricelists share the same currency. What's happening: ----------------- The POS pre-converts product prices from company currency to POS currency in `_load_pos_data_read`. However, `getPrice` in JS never converts between the POS currency and the pricelist's own currency before applying the rule's formula (surcharge, discount, etc.). The fix: -------- In `getPrice`, convert the price from POS currency to pricelist currency before applying the rule, then convert back afterward. Note that we have changed the loading order of the models for `pos_self_order`, such as 'res.currency' records are loaded after 'product.pricelist' ones, because now the loaded currencies depend on the loaded pricelists. opw-6013513 Forward-Port-Of: odoo/odoo#255357
The Documents app now correctly applies sharing changes to every document selected, even when the selection spans more than one page. This prevents rights updates from being applied only to the visible page and ensures the action matches what the user selected.
Original PR description
**Steps to reproduce:** - Install Documents app - Upload more than 80+ files (max page size is 80) - Use the checkbox to select all files on the page - Click the 'Select All' button in the control panel to select allfiles - Use Share action button - Pop-up only takes the current page into account - Rights modifications will not be applied on remaining records **Issue:** `onShare()` only takes current records into account even if the full selection was applied. **Fix:** Fetch all document ids (if needed) before opening the dialog. opw-5957777 Forward-Port-Of: odoo/enterprise#110299
This fix prevents a crash when overtime records are recalculated for employees whose attendance starts or ends at midnight in their time zone. It makes overtime updates more reliable when Absence Management is enabled and an overtime rule is in use.
Original PR description
**Context** - "Absence Management" is enabled in the database settings - Employee has an overtime ruleset selected in their employee settings - That overtime ruleset has a rule with a non-zero `expected_hours` - That employee has 1 or more attendance records that start or end at midnight in their timezone. **Before this commit** When updating overtime records, either via the "Regenerate overtimes" button on the overtime rule, or by simply creating a new attendance record, we'll end up passing around an intervals object that contains no intervals. Then, when we later assume this object will have at least one element, we crash. **After this commit** Guarantee that intervals objects are populated before assuming they are. Further, we remove the opportunity to create an empty intervals object that was exposing this bug. opw-6035270 Forward-Port-Of: odoo/odoo#257986