Wednesday, April 1, 2026
39 changes · saas-19.2
Resolved issues and error corrections
Fixed a bug that caused the AI email composer feature to crash when users selected multiple records before composing an email. The issue occurred because the system couldn't properly handle multiple record IDs. Now the AI feature only activates when a single record is selected, preventing the error and improving the user experience.
Original PR description
Currently an exception is generated when the user tries to click the AI icon in the email composer with multiple records. Steps to produce an error: - Install the `crm` module with the demo data - Go…
Currently an exception is generated when the user tries to click the AI icon in the email composer with multiple records. Steps to produce an error: - Install the `crm` module with the demo data - Go to the CRM list view and select multiple records - Click in `Email` from action > click the `AI` icon on the email composer. Error: `TypeError: int() argument must be a string, a bytes-like object or a real ...` This error is generated because when retrieving the `originalRecordId` from the line [1], the code attempts to remove the first and last characters of a string representation of a list. In the single-selection case, the value is "[4]", so slicing off `[` and `]` correctly yields "4". However, when the user selects multiple records, the value becomes "[4, 5]". Slicing the first and last characters in this case produces "4, 5", and passing this string to Number() results in NaN. As a result, `record_id` becomes `None` when calling `create_ai_draft_channel` method, and passing this None value to int() subsequently raises an error. This commit fixes the issue by assigning `recordId` and `recordModel` only when a single record exists. The record IDs are parsed from their string representation using `JSON.parse`, and the first ID is returned when the list contains exactly one element, or false otherwise. sentry-7201070069 Forward-Port-Of: odoo/enterprise#104873
This fix resolves an issue where the IP (Individual Pension) salary rule was not appearing on employee payslips in the Belgian payroll system. The underlying calculation has been corrected to properly include the IP field, ensuring employees can now see this important compensation component on their payslip documents.
Original PR description
-**Issue**: The IP salary rule was not visible on payslip. -**Fix**: Computation has been adjusted to include the correct field. Forward-Port-Of: odoo/enterprise#110936
This update reverts a previous change to the HR Contract Salary module that affected email functionality. The revert addresses issues introduced in an earlier update and restores the system to a more stable state for salary configuration and applicant management.
Original PR description
Revert https://github.com/odoo/enterprise/pull/111815 Forward-Port-Of: odoo/enterprise#112632
Demo Stripe accounts were not automatically becoming verified when users clicked Connect, remaining in a restricted state. This fix addresses a verification document requirement that was blocking the demo flow. Users can now properly test the Stripe expense feature without manual workarounds.
Original PR description
Step to reproduce: - Click on Connect (demo) - The accounts stay Restricted (even after 5m) This is due to the requirement `company.verification.document` which is present as a pending_verification even when no document is given. Giving it a document such as `file_identity_document_success` which should "marks that document requirement as satisfied" also doesn't work. A work-around is to set the business type to individual since they dont have this requirement. This is a temporary fix, as we want to keep a flow similar to what would have been done in reality. But this is preventing users from testing the feature in 19.0 up to master. Forward-Port-Of: odoo/enterprise#112612
This fix corrects how payment installments are ordered in Peru's electronic invoicing (EDI) documents. Previously, when invoices had multiple payment installments with different due dates, they could appear in the wrong order in the XML file if they weren't created in chronological sequence. Now installments are automatically sorted by their due date, ensuring the correct payment schedule is always reflected in the electronic invoice.
Original PR description
**Steps to reproduce:** * Install `l10n_pe_edi`. * Set SUNAT as the signature provider. * Create a customer invoice. * Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10…
**Steps to reproduce:**
* Install `l10n_pe_edi`.
* Set SUNAT as the signature provider.
* Create a customer invoice.
* Select a payment term with multiple installments (e.g. 50% (15 days) / 30% (10 days) / 20% (5 days)).
* Confirm the invoice and generate the EDI standard UBL document.
**Observed behavior:**
* The XML `<cac:PaymentTerms>` instalment nodes (Cuota001, Cuota002, etc.) are ordered according to the database insertion order of the receivable lines.
* If the payment term lines are created in a non-chronological order, the installments in the XML mix up the `Cuota` ID, amount, and `PaymentDueDate`.
**Cause:**
* `_add_invoice_payment_terms_nodes` iterates over `invoice.line_ids` to generate the installments, but does not sort the receivable account lines by their `date_maturity`.
**Fix:**
* Explicitly call `.sorted('date_maturity')` on the receivable lines before generating the `invoice_date_due_vals_list`.
opw-6035589
Forward-Port-Of: odoo/enterprise#112162This fix resolves crashes that occurred when printing vendor bills with Colombian DIAN support documents, either when duplicating bills or before sending them to DIAN. The system now properly handles cases where DIAN document information hasn't been created yet, displaying a placeholder message instead of failing.
Original PR description
**Steps to reproduce:** * Install the **l10n_co_dian** module. * Enable DIAN 2.1 operation mode: **Support Documents** in settings. * Create a vendor bill using a **DIAN support document** journal. * Confirm the vendor bill. * Click **Print**. **Observed behavior:** * Printing fails with `ValueError: can only parse strings`. **Cause:** * The report template unconditionally called `_l10n_co_dian_get_extra_invoice_report_values()`, which parses `l10n_co_dian_attachment_id.raw` via `etree.fromstring()`. * On duplicated bills, `l10n_co_dian_document_ids` (and thus the computed `l10n_co_dian_attachment_id`) is empty, so `.raw` is `False`. **Fix:** * Wrap the QR code / CUFE / signing section in the report template with `t-if='o.l10n_co_dian_attachment_id'` so it is only rendered when the DIAN attachment exists. opw-5930173 Forward-Port-Of: odoo/enterprise#109912 Forward-Port-Of: odoo/enterprise#108645
A bug was fixed where products were being incorrectly deleted when a product template had only one product variant. This ensures that products are properly retained during website generation, preventing accidental data loss.
Original PR description
product.product records were being removed when they should not have been in the case that the product.template only has one product.product record. This commit fixes this issue by accounting for the case where there is only one product.product record. Forward-Port-Of: odoo/enterprise#112519
This fix resolves a system error that occurred when creating employee contracts with work schedules that have zero working hours. Previously, the system would crash when trying to calculate hourly wages in this scenario. The fix prevents this error, allowing users to create contracts even with empty work schedules.
Original PR description
When a working schedule has 0 working hours, creating a contract raises a traceback during hourly wage computation. Steps to reproduce the error: - Install ``l10n_au_hr_payroll`` module - Switch to ``My Australian Company`` - Create a working schedule without any working hours - Create an employee and assign this working schedule > Save - Click on Contracts smart button Traceback: ```py ZeroDivisionError: float division by zero ``` https://github.com/odoo/enterprise/blob/bd746aa43f549c4f7813a849e00447b55e084f21/l10n_au_hr_payroll/models/hr_contract.py#L113-L115 The hourly wage is computed using the working schedule’s hours per day. When this value is 0, it results in the above traceback. sentry-7355577930 Forward-Port-Of: odoo/enterprise#112450 Forward-Port-Of: odoo/enterprise#111629
This fix resolves an issue where AI-powered conversations with agents were broken in the AI app. The update corrects how the system identifies conversation participants, preventing the app from incorrectly treating conversations as self-chats, which was causing unwanted side effects like out-of-office banners appearing. Agent workflows that depend on proper participant identification now work correctly.
Original PR description
Override AI thread correspondent computation to keep the base behavior but clear the correspondent when it resolves to the current user in ai_composer/ai_chat. This avoids self-chat fallback side effects (like OOO banner) while preserving agent flows that rely on a real non-self correspondent. source of this crash: https://github.com/odoo/enterprise/pull/108217 Forward-Port-Of: odoo/enterprise#112392 Forward-Port-Of: odoo/enterprise#111736
This fix corrects how shifts are split when using the daily view in the planning schedule. Previously, splitting a shift within a single day would incorrectly snap the resulting shifts to standard working hours (8am-5pm), creating duplicate time entries outside the original shift. Now, shifts split within a day are properly divided at the exact requested time without adding extra hours.
Original PR description
Since odoo/enterprise#69963, splitting a shift in Gantt view snaps the resulting shifts to the standard working hours (e.g., 08:00 to 17:00). This behavior makes sense when splitting a multi-day shift across a day off, where we want to generate a full working day for the day off as well. However, when splitting a shift within a single day (day scale), this behavior is not wanted, otherwise creating two shifts as follows: 1. A shift from [Original Start] to 5pm 2. A shift from 8am to [Original End] Clearly, the shift is duplicated with the wrong timeframes and adding time outside the original shift's hours. This commits ensures that, when splitting a shift in hours (i.e., when using `day` view scale), the shift is appropriately split at the time requested. For instance: 1. A shift from [Original Start] to [Split Time] 2. A shift from [Split Time] to [Original End] task-5387243 Forward-Port-Of: odoo/enterprise#105991
This fix resolves an issue in Web Studio where invisible field attributes were being lost when users added group restrictions to fields. Previously, when a field was restricted to certain user groups, the original invisible condition would disappear from the editor, even though it was still applied to the actual view. Now the system properly preserves these invisible attributes so users can see and edit them correctly.
Original PR description
Steps to reproduce ================== - Install contacts,web_studio - Login as admin - Go to contacts - Open any record - Open studio - Click on any field - Add the "Role / Portal" group - Toggle the…
Steps to reproduce ================== - Install contacts,web_studio - Login as admin - Go to contacts - Open any record - Open studio - Click on any field - Add the "Role / Portal" group - Toggle the "Show invisible Elements" checkbox - Click on the same field => The field is marked as invisible - Add an invisible condition => The invisible condition is lost (but still applied on the view) Cause of the issue ================== In studio, when fetching the view, the invisible attribute is set to True when the user does not have access to the field (when he is not part of the groups). The goal is to make the field invisible in studio unless the "Show invisible Elements" is toggled. But this causes the actual value of the invisible attribute to be lost. Note that this also applies to the column_invisible attribute. Solution ======== If an invisible/column_invisible attribute is present on the nodes with missing access, we copy the actual value to the `actual_invisible` attribute. We then use that value in the editor, when present. opw-6026971 Forward-Port-Of: odoo/enterprise#112084 Forward-Port-Of: odoo/enterprise#111299
This fix ensures that when Provident Fund (PF) is disabled in payroll settings, it no longer appears in the Salary Configurator tool. Previously, the disabled PF benefit could still be displayed and cause errors when users tried to update their salary package. Now the system properly hides PF and prevents related technical errors.
Original PR description
Before: - PF toggle disabled in payroll settings, but “Provident Fund” could still appear in Salary Configurator (Extra Benefits). - Hiding PF from displayed values could make `/salary_package/update_salary` crash with missing `l10n_in_pf_employee_amount`. After: - When `l10n_in_provident_fund` is disabled, PF benefit is filtered out from `_get_benefits_values`. - Empty benefit types are removed, so “Extra Benefits” no longer shows if it only contained PF. - PF initial value is dropped from payload values. - Missing PF value is defaulted to `0.0` in `_get_new_version_values`, preventing update/submit errors. task-6008086
This update fixes how annual leave provisions are calculated in Turkish payroll. The provision now applies only to active employees after their first year, uses clearer rate displays, and is properly included in net salary calculations. This ensures more accurate and transparent payroll processing for Turkish operations.
Original PR description
## Before: - Annual Leave Provision showed a confusing rate value. - It could be triggered too early around the first-year period. - “Excluded from Net” was checked. ## After: - Annual Leave Provision is applied only for active employees after one year. - The amount is based on monthly working days, while the displayed rate stays clear at 100%. - “Excluded from Net” is unchecked. Task-6033568
This fix resolves a system crash that occurred when confirming sales orders containing both regular dropship products and subscription-based dropship products. The issue was caused by inconsistent date format handling in the purchase order system. By standardizing how dates are processed, the system now correctly handles mixed product types without errors.
Original PR description
**Steps to reproduce:** * Install *sale_management*, *sale_subscription*, and *stock* modules. * Go to *Settings* and enable *Dropshipping*. * Create two products: * One *normal dropship* product. *…
**Steps to reproduce:**
* Install *sale_management*, *sale_subscription*, and *stock* modules.
* Go to *Settings* and enable *Dropshipping*.
* Create two products:
* One *normal dropship* product.
* One *dropship + subscription* product.
* Create a *Quotation*.
Add both products to the order.
* Confirm the quotation.
**Observed behavior:**
* A traceback occurs during confirmation:
File '/home/odoo/workspace/odoo19/odoo/addons/purchase_stock/models/stock_rule.py', line 159, in _run_buy
date_planned = po.date_planned or min(v['date_planned'] for v in po_line_values)
TypeError: can't compare datetime.datetime to datetime.date
**Cause:**
* In *_run_buy*, the system computes the earliest *date_planned* using:
https://github.com/odoo/odoo/blob/4056fa8036ddad11c898cd775b7fa21ba4f8a5de/addons/purchase_stock/models/stock_rule.py#L159
* Subscription products set *date_planned* as *datetime.date*,
https://github.com/odoo/enterprise/blob/a88c64a224805d95b60a20c502428897655dba53/sale_subscription_stock/models/sale_order_line.py#L153
`current_period_start = self.order_id.last_invoice_date or
self.order_id.start_date or fields.Date.today()`
* while normal products set *date_planned* as *datetime.datetime*.
https://github.com/odoo/odoo/blob/4056fa8036ddad11c898cd775b7fa21ba4f8a5de/addons/sale_stock/models/sale_order_line.py#L286
before min() It call `_prepare_purchase_order_line_from_procurement`,
the value is assigned directly from `values.get('date_planned')`, and conversion
with `fields.Datetime.to_datetime()` only happens conditionally:
https://github.com/odoo/odoo/blob/98e6e929bf8e0c34ec77fb9d07ef253e0abf681c/addons/purchase_stock/models/purchase_order_line.py#L347-L351
As a result, some values remain `date` while others are `datetime`,
* When both are present in *po_line_values*, Python cannot compare the
two types, causing the crash.
**Fix:**
So by moving the `fields.Datetime.to_datetime()` cast to the initial
assignment of `res['date_planned']`, so it is always a `datetime`
regardless of the source, and removing the now-redundant cast inside
the `if` block.
---
opw-6034079
---
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#255063This update fixes an error that occurred when users tried to view custom snippets they had created from map components. The issue happened because the system couldn't find the original map snippet when certain features were disabled. We've also improved the naming of map snippets to make it clearer which one is the Google Map option, reducing confusion when creating custom snippets.
Original PR description
Steps to reproduce: 1. Go to the website editor (ensure developer mode is off) 2. Drag and drop a Map snippet onto the page 3. Click on the newly placed snippet and save it as a custom snippet 4.…
Steps to reproduce: 1. Go to the website editor (ensure developer mode is off) 2. Drag and drop a Map snippet onto the page 3. Click on the newly placed snippet and save it as a custom snippet 4. Enable developer mode and refresh the website editor 5. Add a new Google Map snippet to the page a. The Google Map snippet is the one where the icon shows a map with a pin on the **left side**. 6. In the wizard, enter your valid API key and click Save a. Alternatively, you can use Odoo inspector to write any string into the `google_maps_api_key` field of the `website` model to simulate the above 7. Disable developer mode and refresh the website editor 8. Click one of the categories in the editor side panel to open the snippets browser 9. Click into the 'Custom' snippets category 10. Observe the error Depending on whether or not you have a Google Maps API key configured on your website, either the `s_map` or `s_google_map` base snippet will be disabled/hidden. When a user has created custom snippets out of the disabled base snippet, you will recieve the error mentioned above when the snippet browser attempts to load in these custom snippets, as it will be unable to load the base snippet. To fix this, we check if an original snippet was found when loading in a custom snippet. If not, we will not load in the custom snippet to avoid confusion. This error does not occur in Developer Mode, as both base snippets are always enabled in this case. Aditionally, we also clarify which snippet is the Google Map snippet to avoid confusion for the user when creating custom snippets. opw-5933787 Forward-Port-Of: odoo/odoo#256847 Forward-Port-Of: odoo/odoo#250236
This fix resolves an issue where invoice delivery notifications (webhooks) were being blocked with access errors when sent between user accounts. The system was incorrectly applying access restrictions to webhook processing, preventing invoices from being properly delivered. This update restores the ability to send and receive invoices through the automated notification system.
Original PR description
- Register your user (on a db that allows webhook). - On another registered account, send an invoice to the first one. => A webhook call has been made, resulting into a 403 Forbidden. Following some changes on access rights checks, the webhook don't work. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256607
This fix corrects an issue where branch companies using their parent company's VAT for PEPPOL registration were incorrectly shown a participation role setting in the configuration. Since branches should only be able to send documents (not receive), this setting is now hidden from the user interface to prevent confusion and ensure proper system behavior.
Original PR description
In v19.0 -> master, if a branch company used the VAT of the parent company to register for peppol, the peppol participation role would be shown in the configuration settings, with a default value being "Sending and receiving", And since branches in this case should be able to ONLY send, the setting shouldnt be visibile to the user. task-none Forward-Port-Of: odoo/odoo#256820
This fix restores the ability to sort grouped lists by date and datetime fields in the Accounting module. Users can now click on the Date column header in grouped views (like Deferred Entries) to sort the data, which was previously broken. This improves the usability of financial reporting and data organization features.
Original PR description
Steps to reproduce 1. Open Accounting > Customers > Invoices and create an invoice with deferred dates. 2. Open the invoice and click the Deferred Entries smart button. 3. In the grouped list view,…
Steps to reproduce 1. Open Accounting > Customers > Invoices and create an invoice with deferred dates. 2. Open the invoice and click the Deferred Entries smart button. 3. In the grouped list view, click the Date column header to sort. 4. Nothing happens. Issue The [IMP] web: Grouped kanban/list in a single RPC (https://github.com/odoo-dev/odoo/commit/26c37c9c070107f8bd753cb8a6d8343384fdd7bf) refactor introduced a regression. _get_read_group_order() [1] iterated over the provided aggregates list to build the ORDER BY clause. Fields with an aggregator attribute that are not included in the aggregates list (e.g. date fields, which getAggregateSpecifications() excludes) were silently dropped from ORDER BY. [1] https://github.com/odoo/odoo/blob/26c37c9c070107f8bd753cb8a6d8343384fdd7bf/addons/web/models/models.py#L496-L514 Solution Add a fallback in _get_read_group_order() so that when fname is neither a groupby field nor present in the provided aggregates list, the method checks field.aggregator directly and appends `fname:aggregator direction` (e.g. `date:min ASC`) to the ORDER BY string. The ORM's _read_group_orderby() already accepts such specs in ORDER BY even without them being in SELECT. opw-6044059 Forward-Port-Of: odoo/odoo#256592
This fix resolves an issue where the coupon code entry form was being hidden after a customer entered a promotional code in their shopping cart. The form will now remain visible and functional when a pricelist with an E-commerce Promotional Code is active, allowing customers to continue using coupon codes as intended.
Original PR description
Issue: --- If the current pricelist has `E-commerce Promotional Code` set, the coupon form is hidden. Steps to reproduce: --- 1- Create a pricelist and set `E-commerce Promotional Code`. 2- Navigate to the cart in website. 3- Enter pricelist code in the coupon form. Result: Once the code is entered, pricelist is changed and the coupon form is hidden. Cause: --- This is done intentionally on #23713. However, it seems it's not relevant anymore. Fix: --- We can remove `force_coupon` condition from `reduction_code` template. However `force_coupon `is also used inside xpath expression in `reduction_coupon_code` template. In order not to break stable we can keep `t-set="force_coupon"` inside the `reduction_code` template, and remove it on master. opw-5977474 Forward-Port-Of: odoo/odoo#256789 Forward-Port-Of: odoo/odoo#252518
The Bluetooth caliper driver was sending measurement readings without a success status flag, causing the system to incorrectly show false disconnection warnings. This fix ensures that successful measurements are properly marked as complete, eliminating the misleading alerts and improving the reliability of Bluetooth device readings.
Original PR description
When a measurement was successfully read via Bluetooth, the driver broadcasted the `value` without the `status` flag. The frontend JavaScript received the `value` but rejected the payload because the `status` was not explicitly marked as successful, leading to a fake disconnection warning. opw-5473691 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256860
This fix resolves a bug that prevented purchase orders from being confirmed in certain cases. A previous system update changed the name of a technical field from 'product_uom' to 'product_uom_id', but one part of the code was missed. This update corrects that reference so purchase orders can be confirmed without errors.
Original PR description
A big refactor of UOM in saas-18.1 (https://github.com/odoo/odoo/pull/184131) accidentally left a reference to the `product_uom` field on `purchase.order.line`. But that field was renamed to `product_uom_id` in https://github.com/odoo/odoo/pull/186250. In rare edge-cases, if we it `supplierinfo['product_uom_id'] = line.product_uom.id` while confirming a purchase order, it will block it because of a traceback: ``` supplierinfo['product_uom_id'] = line.product_uom.id ^^^^^^^^^^^^^^^^ AttributeError: 'purchase.order.line' object has no attribute 'product_uom'. Did you mean: 'product_id'? ``` This PR fixes the issues by accounting for the field rename. OPW-6068125 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256768 Forward-Port-Of: odoo/odoo#256416
This fix ensures that archived accounts are properly checked when creating unaffected earnings accounts, preventing validation errors during system upgrades. Previously, the system would fail when an archived account had the same code as a new unaffected earnings account, which was causing upgrade failures for companies using the Saudi Arabia localization module.
Original PR description
Archived accounts are also searched when looking for duplicate codes since https://github.com/odoo/odoo/commit/cd8d9718427e48aaa79be21f9a08e89b79b573f9 We need to check archived accounts as well when creating the unaffected earnings account, to avoid triggering the validation if an archived account has the same code. This is failing on upgrades with `l10n_sa` installed where the account `sa_account_999999` has been archived. Forward-Port-Of: odoo/odoo#256112
This fix resolves an issue where replacing the contact form on the /contactus page would cause submission errors. The problem occurred because the system was using email settings from the old form configuration even after the form was deleted and recreated. The fix ensures that email settings are only applied when the original form is still present, preventing mismatches during form submission.
Original PR description
Problem: There is a data-for span in the /contactus page that sets specific values on the page's form. If this form is deleted and a new form is added, an error will occur when trying to submit the new form. This is because the value set for website_form_signature will use the email set in the data-for, which will not match with the new form. Purpose: Modify the code that sets the website_form_signature value to ensure that the original form is present as well if using the data-for values. Steps to Reproduce in Runbot: 1. Use the Website Editor to delete the form on the /contactus page and create a new one. 2. Attempt to submit the new form. opw-5956030 Forward-Port-Of: odoo/odoo#253410
This fix resolves an issue where cancelled events from Microsoft Calendar would cause synchronization errors if they hadn't been previously synced to Odoo. The system now properly handles cancelled events during the sync process, preventing errors and ensuring smooth calendar synchronization between Microsoft and Odoo.
Original PR description
Before this commit, when syncing events from Microsoft, if there was a cancelled event that was not yet synchronized with Odoo, calling browse on event.odoo_id would raise an error as it would be None. opw-5917677 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256827
This fix resolves an issue where sales orders and other documents using date-based sequences would display incorrect month/year information in their reference numbers. When a document was dated for a future month, the sequence number would correctly use the future month's counter, but the prefix would incorrectly show the current month. The fix ensures the date used for formatting the sequence prefix matches the date used to select the sequence number.
Original PR description
## Issue When using date_range in a `ir.sequence`, the placeholders `%(...)s` would be based on a different date than the sequence number. ## Steps to reproduce This is one example among other use…
## Issue
When using date_range in a `ir.sequence`, the placeholders `%(...)s` would be based on a different date than the sequence number.
## Steps to reproduce
This is one example among other use cases causing this issue.
1. Install *Sales* (`sale_management`)
2. In Settings > Technical > Sequences, select the `sale.order` sequence
- Set the Prefix to something containing the current month (e.g. `S%(y)s/%(month)s/`)
- Enable *Use subsequences per date_range* (`ir.sequence.use_date_range`)
- Add a row for the current month, with *Next Number* set to 1
- Add a row for the next month, with *Next Number* set to 5
3. Create a Sales Order:
- Any Customer
- Any Product
- Set the *Quotation Date* to next month
- Confirm
4. **The resulting Sales Order uses the sequence from next month (= its name ends with 5), but replace the `%(month)s` placeholder by the current month.**
<img width="541" height="130" alt="image" src="https://github.com/user-attachments/assets/6ace81f9-1ce2-4401-a9ba-383673a20981" />
The original issue reported by ticket 5950028 showed a similar issue with dropshipped Purchase Orders, which would use the date of delivery for the sequence number, and the current month for the placeholder in the prefix/suffix.
## Cause
When interpolating the prefix/suffix of a sequence, the date used by default is `datetime.now(self.env.tz)`. If provided, the context keys `ir_sequence_date` and `ir_sequence_date_range` are used instead.
https://github.com/odoo/odoo/blob/877289cf4d9725e12b355f482308150fe170e816/odoo/addons/base/models/ir_sequence.py#L211-L216
In the `IrSequence._next` method, the correct `ir.sequence.date_range` is chosen, based on the sequence date provided (which is the *Quotation Date* in our steps to reproduce) and the `ir_sequence_date_range` is passed as a context key to be used in the `_interpolation_dict` function later.
https://github.com/odoo/odoo/blob/98e6e929bf8e0c34ec77fb9d07ef253e0abf681c/odoo/addons/base/models/ir_sequence.py#L261-L270
**The `ir_sequence_date` is not passed as a context key, which will make `_interpolation_dict` use `datetime.now(...)` to interpolate the placeholders in the prefix/suffix.**
opw-5950028
Forward-Port-Of: odoo/odoo#256449
Forward-Port-Of: odoo/odoo#256320Mozambique users were seeing the incorrect Brazilian tax ID label "CPF/CNPJ" on their sales orders and invoices instead of the correct Mozambique tax ID label "NUIT". This fix adds the proper tax ID label for Mozambique, ensuring users see the correct terminology on their business documents.
Original PR description
Currently the "Tax ID" title used e.g. on sales orders, invoices, etc. was translated as "CPF/CNPJ" in Portuguese, which is the tax ID used in Brazil. However, in Mozambique, the tax ID is called "NUIT", and there is no language variant for Portuguese in Mozambique. This caused Mozambique users to see "CPF/CNPJ" instead of "NUIT" on their documents, which was wrong. This commit adds a `vat_label` field for Mozambique to display the correct tax ID label. Issue reported by functional support. Forward-Port-Of: odoo/odoo#256603
This update fixes a validation issue in the payment demo module to ensure payment provider configurations are properly checked. The fix prevents potential errors when processing payments by validating that the demo payment provider is correctly configured before use.
Original PR description
opw-3097856 Forward-Port-Of: odoo/odoo#256362
The self-ordering system has been optimized to load customer data more efficiently. Previously, the system was loading all customer information even when only a small portion was needed, which caused slowdowns for customers with large data profiles. This fix ensures only the essential customer details are loaded during self-ordering, resulting in faster checkout and ordering experiences.
Original PR description
Partner data loading for self-ordering was not optimized, leading to performance issues when the partner had a lot of data. This commit optimizes the partner data loading by only loading the necessary fields for self-ordering. Forward-Port-Of: odoo/odoo#256494 Forward-Port-Of: odoo/odoo#253563
This fix corrects the display of projected margins in the sales reporting module. Previously, the system was showing an incorrect default list view when users accessed projected margin information. The update ensures the correct custom view is displayed, providing users with accurate and properly formatted margin data.
Original PR description
Specify the custom list view for the projected margin action window instead of showing the default `sale.report` list view in saas-19.2 --- task-6084014
This fix resolves an issue where employees couldn't see their time off allocations when creating new time off requests. The problem occurred when employee profiles lacked a country setting or when allocations were for different time periods. The update now properly displays country-specific leave types and correctly evaluates allocations based on the requested dates rather than today's date.
Original PR description
**Steps to Reproduce:** 1. Open Time Off -> Management -> Allocations 2. Create a new allocation with validity period in the past (Jan 1, 2025 to Dec 31, 2025) and Country(Eg: USA) and validate it.…
**Steps to Reproduce:** 1. Open Time Off -> Management -> Allocations 2. Create a new allocation with validity period in the past (Jan 1, 2025 to Dec 31, 2025) and Country(Eg: USA) and validate it. 3. Open Managements -> Time Off 4. Create a time off with date, say Jan 10, 2025 5. You will not see the allocation type you created earlier **Bug cause:** When an employee profile lacked a 'country_id', they were unable to see country-specific leave types because the search was incorrectly filtering for 'Global' types only. Additionally, the dropdown was failing to show valid allocations for previous or future years because the compute context was losing the user-selected dates, falling back to 'today' and returning 0 balances. **Solution:** - Work entry type searches now fall back to the Company's country if the Employee's country is not set. - Explicit date context (default_date_from/to) is passed through filtered_domain to ensure allocations are evaluated for the requested period rather than the current date. - The '_compute_leaves' logic now matches allocations by record ID instead of name string to avoid choosing generic types when country specific type is available. **Task:** 6067425 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Tax names in the Spanish localization module are now displayed in Spanish instead of English, improving clarity for Spanish users. This fix ensures that tax information is presented in the appropriate language for the target market, reducing confusion and improving the user experience.
Original PR description
It was a previous dev in which the fw-port failed. Here is the old [PR](https://github.com/odoo/odoo/pull/238857) The tax names were displayed in English, and it's confusing for the Spanish users. Now, the taxes are displayed in spanish task-6041023 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256182 Forward-Port-Of: odoo/odoo#255074
This fix resolves an issue where importing orders with line-level charges (allowances and surcharges) would fail. The system now correctly processes quantity and tax information for both regular order lines and charge lines, ensuring smooth order imports from electronic documents.
Original PR description
When importing orders with line-level charges, the import would fail because the `quantity` key was not being renamed to correct quantity keys (`'product_uom_qty'` for sale order and `'product_qty'` for purchase order) for allowance charge lines. The issue occurred because the key renaming was only applied to the main lines_vals list after calling `_import_lines()`, but not to the `allowance_charges_line_vals` that were created separately. Also the key for taxes returned in `_get_line_vals_list` method in `purchase.order` model is `'taxes_id'` which is not aligned with the `purchase.order.line` model. This fix properly handles the quantity key renaming for both regular lines and allowance charge lines and updates `'taxes_id'` key value to `'tax_ids'`, preventing the AttributeError when accessing the quantity key during order line creation. Forward-Port-Of: odoo/odoo#245411
This fix improves the website builder's behavior when users click on nested elements like footer containers, social media icons, and form buttons. Previously, the wrong options panel would open. Now the system intelligently displays the parent element's options when appropriate, making the builder more intuitive and reducing user confusion.
Original PR description
Since [folding of groups of options], the last group, the one corresponding to the element the user clicked, is unfolded. In some cases, it is likely that the user intended to open the parent element's options: - footer: when clicking on the container or the copyright - social media snippet: when clicking on an icon - accordion: when clicking on accordion item - timeline: when clicking on milestone row - form: when clicking on the row of the submit button - submit button's row: when clicking on the button With this commit, in those cases, the ancestor's options are unfolded as well. Steps to reproduce: - Open website builder - Click on the footer - Bug: the container's options open instead of the footer's options [folding of groups of options]: 64d35ccd6fade9e0473686b8484f561b5f4215ce task-6069263
This fix corrects an issue where loyalty programs were incorrectly matching and awarding points even when price list functionality was disabled. Previously, disabled price lists were still being retained in the system, causing loyalty rewards to be applied incorrectly. This update ensures that when price list features are turned off, loyalty programs respect that setting and only match appropriately.
Original PR description
When `use_pricelist` is disabled, `available_pricelist_ids` retains previously configured pricelists. This caused loyalty programs restricted to a specific pricelist to still match and accumulate points incorrectly. opw-5952960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256398 Forward-Port-Of: odoo/odoo#252718
Manufacturing orders now correctly calculate their scheduled end dates by accounting for work center operating hours instead of assuming 24/7 operation. Previously, a 1440-minute job at an 8-hour-per-day work center would show completion in 1 day instead of the correct 4 days. This fix ensures more accurate production scheduling and delivery date forecasting.
Original PR description
**Issue** The scheduled end date of a manufacturing order incorrectly assumes that the work center operates 24 hours a day. **Steps to reproduce** 1. Create a manufacturing order with: - A work order…
**Issue** The scheduled end date of a manufacturing order incorrectly assumes that the work center operates 24 hours a day. **Steps to reproduce** 1. Create a manufacturing order with: - A work order with an expected duration of 1440 minutes. - A work center configured to work 8 hours per day. 2. Observe that the scheduled end date is computed as if the work center operates 24h/day resulting in an end date 1 day instead of 4 after the starting date. **Cause** The `date_finish` computation: https://github.com/odoo/odoo/blob/680085b55728dcb000e7bb4277bb83b0e4e2ce91/addons/mrp/models/mrp_production.py#L745C1-L746C105 does not take into account neither the work center’s calendar nor the workorder dependency when estimating the duration. **Solution** Use `_get_first_available_slot`: https://github.com/odoo/odoo/blob/5d75037d4f81d71a50394c3d390c420967766731/addons/mrp/models/mrp_workcenter.py#L332 to consider workcenter availability, inspired from when a workorder is planned: https://github.com/odoo/odoo/blob/5d75037d4f81d71a50394c3d390c420967766731/addons/mrp/models/mrp_workorder.py#L527 **Additionnal notes** - If a workcenter of at least one workorder is unavailable, just fallback on the previous computation. - The solution does not take workorder dependencies into account due to related technical limitation see https://github.com/odoo/odoo/pull/232805 for an earlier attempt to handle dependencies. - Our test rely on the assertAlmostEqual for the same reason than https://github.com/odoo/odoo/commit/e6c958ca226bd8ef7e518243c93e40b92b9b5919 opw-[5084120](https://www.odoo.com/web#id=5084120&view_type=form&model=project.task) Forward-Port-Of: odoo/odoo#254071 Forward-Port-Of: odoo/odoo#240617
The meeting panel in Odoo's mail module was displaying white text on a white background, making it completely unreadable in light theme. This fix removes an incorrectly applied dark theme styling class that was inverting text colors, restoring normal readability.
Original PR description
Before this PR, .o-simulateDarkTheme is applied to the panel in meeting mode. This class inverts the text color, making it white on white. This PR removes the class, which seems to have been applied by mistake. task-6054300 Before: <img width="776" height="1009" alt="image" src="https://github.com/user-attachments/assets/6d7ad6c3-6593-43ba-9101-c8960f3e649f" /> After: <img width="766" height="994" alt="image" src="https://github.com/user-attachments/assets/0cf6b3b6-388c-44bc-b697-760132c06ede" />
This fix prevents users from accidentally creating multiple work entry types with the same code within the same country. Previously, a validation check was missing, allowing duplicate codes to be created. The system now properly validates and blocks duplicate work entry type codes to maintain data integrity and prevent configuration errors.
Original PR description
It was previously possible to create two work entry types with the same code in the same country. It was due to a missing `raise` before the `UserError`. The condition to raise the exception was not correct either. So it has been changed to prevent having two work entry type codes covering the same country. task-6037156
Fixed an issue in the online shop where product images weren't updating when customers hovered over different product attributes. The fix ensures that when shoppers hover over options like size or color, the product image changes to show the correct variant. This improves the shopping experience by providing accurate visual feedback.
Original PR description
Steps to reproduce: - Go to the shop page. - Hover over any attribute on a product tile that displays attributes. Issue: - The variant image does not update on attribute hover. Cause: - The `srcset` attribute was introduced for website images in https://github.com/odoo/odoo/commit/36e680feca4884940e020119de6a13cd7f927516. - Only the `src` attribute of the image is updated on hover, while the `srcset` remains unchanged. - Since browsers prioritize `srcset` over `src`, the displayed image does not change. Fix: - Remove the `srcset` when hovering over an attribute to ensure the updated `src` is used. - Restore the original `srcset` when the hover ends. opw-6030289
This fix ensures that when users create a toggle list from a heading element in the HTML editor, the heading style is preserved as the title of the new toggle list. Previously, the system would incorrectly use a default base container instead of maintaining the original heading format, which could affect document formatting and consistency.
Original PR description
**Current behavior before PR:** If current block is heading and a toggle list is created from powerbox, newly created toggle list has baseContainer as title element, even though the anchor block was heading. **Desired behavior after PR:** This PR ensures that if toggle list is created from heading then title element of toggle list will be same is heading. task-5975804 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr