Daily updates from Odoo
Wednesday, April 1, 2026
36 changes · saas-19.1
Resolved issues and error corrections
Fixed an access error that prevented Field Service users from adding customers to tasks. The issue occurred when the system tried to update partner information without proper permissions. The fix securely handles these updates so Field Service users can now complete this common task without errors.
Original PR description
Steps to Reproduce: - 1. Log in with a user having only "Field Service > User" access. 2. Create a new task in an field service project. 3. Add a customer on the task. 4. Access error is raised. Issue: - - Field service users could not create a task with a customer. - An access error appeared during task creation. Cause: - - When a customer was added to the task, the partner_phone inverse method was triggered. - This method attempted to write on the partner record. Solution: - - Used sudo() in the inverse method to update the partner phone securely, bypassing restricted access. task-5039657 Forward-Port-Of: odoo/enterprise#112650 Forward-Port-Of: odoo/enterprise#93969
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 document if they weren't created in chronological sequence. Now installments are automatically sorted by their maturity 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#112162The ESG Activity Type model had a confusing description that was identical to the standard Activity Type model. This fix updates the description to "Activity Type ESG" to clearly distinguish it as an ESG-specific feature. This helps users understand which activity type model they're working with in the system.
Original PR description
Before this commit, the description of `esg.activity.type` model is the same than the `activity.type` one defined model which could be confusing. This commit updates the description of `esg.activity.type` model to set Activity Type ESG to explicitly mention that model is used in ESG. Forward-Port-Of: odoo/enterprise#112680
Demo Stripe accounts in the expense module were not automatically verifying when users clicked Connect, remaining in a restricted state indefinitely. This fix resolves the verification document requirement issue that was blocking users from testing the Stripe integration feature. Users can now properly test the expense and Stripe payment functionality without 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 update reverts a previous change to the salary configuration system that affected how emails are handled. The revert restores the system to its previous working state, ensuring that salary-related communications function as expected for HR teams managing employee contracts.
Original PR description
Revert https://github.com/odoo/enterprise/pull/111815
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. Now the system handles this edge case gracefully, 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
Fixed an issue where splitting a shift within a single day in the planning calendar was incorrectly snapping to standard working hours (8am-5pm), causing duplicate shifts with wrong timeframes. Now when splitting a shift in the daily view, it correctly divides at the exact time requested without adding extra hours outside the original shift.
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 error that occurred when viewing the General Ledger consolidation report with multiple companies selected. The system was trying to use account code information that wasn't being retrieved from the database, causing the report to fail. Now the report correctly displays consolidation data across multiple companies without errors.
Original PR description
### Issue before this commit: When opening the General Ledger consolidation with multiple companies selected, a traceback was displayed with a KeyError: 'account_code'. ### Steps to reproduce the…
### Issue before this commit: When opening the General Ledger consolidation with multiple companies selected, a traceback was displayed with a KeyError: 'account_code'. ### Steps to reproduce the issue: 1. Select two or more companies from multi company menu 2. Accounting / Reporting / Ledgers / General Ledger 3. Posted Entries, Accrual Basis button 4. Pick Consolidation 5. Error ### Cause of the issue: When more than one company is selected, the General Ledger consolidation groups journal entries by multiple parameters in an increasingly strict hierarchy. One of these parameters is account_code, which is required only in a multi-company context (as account_id alone is sufficient when a single company is selected). However, the SQL query was not properly adapted to handle this case. The account_code field was used as a grouping key but was not retrieved from the database, resulting in a KeyError. ### Reason to introduce the fix: To ensure that the General Ledger consolidation can be correctly displayed in a multi-company context and to prevent runtime errors. opw-5933074 Forward-Port-Of: odoo/enterprise#109036
This fix resolves a bug where products were being incorrectly deleted when a product template had only one variant. The issue has been corrected to properly handle single-product scenarios, ensuring products are no longer unintentionally removed from your catalog.
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.
This update fixes issues with the bank reconciliation feature on mobile devices. When a bank transaction is fully reconciled, unnecessary buttons like "Reconcile" are now properly hidden on mobile (they were already hidden on desktop), preventing errors when users accidentally click them. Additionally, the reconciliation details now display correctly instead of showing "[object Object]" text.
Original PR description
Currently, when a line is fully reconciled, we display all the moves, name of the reconciliation, and we hide the `Reconcile`, `Set Partner`, ... buttons, has the line is reconciled, we don't need the buttons. But in mobile, we still display the buttons (like `Reconcile`), leading to a traceback when clicking on it. Furthermore, instead of showing the moves name, we show a `[object Object]`. This bug was probably introduced here: https://github.com/odoo/enterprise/pull/101692 task-6058911
Fixed an issue where the IP (Individual Pension) salary rule was not appearing on employee payslips in the Belgian payroll system. The computation logic has been corrected to properly display this important salary component, ensuring employees can see the complete breakdown of their compensation.
Original PR description
-**Issue**: The IP salary rule was not visible on payslip. -**Fix**: Computation has been adjusted to include the correct field.
Fixed an issue where users couldn't preview sales orders for subscription upsells that don't contain recurring products. The system now allows previewing these upsells, making the workflow smoother for sales teams managing non-recurring add-on sales.
Original PR description
When you have an upsell that does not have recurring products, you cannot preview the SO, so we've allow it in this specific case as it is allowed by the constraint on the model
Users with proper permissions were unable to check out visitors from the Frontdesk app due to an incorrectly configured access control filter. This fix corrects the permission logic so authorized users can now successfully complete the visitor checkout process without encountering error pages.
Original PR description
## Short functional explanation of the error When a user checks in, a mail is sent in the chatter, containing a button 'Check out Visitor'. When a user who should have access to the Check Out feature clicks on the button, we are redirected to a 'Not Found' page. ## Reproduction Steps 1. Go to Frontdesk. Click on Open Desk and check in a visitor. 2. Go back to the Frontdesk app. Click on visitors. 3. Click on the visitor you just checked in. 4. Click on the 'Check Out Visitor' button in the chatter. ### Expected behavior A page should appear with the text: 'The visitor has been successfully checked out'. ### Unexpected behavior A 'Not found' page pops up. ## Origin of the issue We filter users who can benefit from the check-out feature using groups. However, the group used to perform this filter is written incorrectly, leading to a condition that is always True, and always returning a request not found. __ opw-5937326 Forward-Port-Of: odoo/enterprise#108331
Fixed a bug that caused the AI email composer to crash when users selected multiple records and clicked the AI icon. The issue occurred because the system couldn't properly handle multiple record IDs. Now the AI composer 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
This fix resolves a crash that occurred when trying to print vendor bills using Colombian DIAN support documents before they were sent to the tax authority. The system now displays a helpful message indicating that the tax code will be generated once the document is submitted, instead of failing with an error.
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** before sending to DIAN. **Observed behavior:** * Printing fails with `AttributeError: 'bool' object has no attribute 'replace'`. **Cause:** * The method `_l10n_co_dian_get_extra_invoice_report_values()` unconditionally accessed `document.datetime.replace()`. * Before sending to DIAN, `_l10n_co_dian_get_last_accepted_document()` returns an empty recordset, so `document.datetime` evaluates to `False`. **Fix:** * Add a check for empty document recordset in `_l10n_co_dian_get_extra_invoice_report_values()` and return a placeholder message indicating the CUDS code will be created once the document is sent, similar to contingency invoice handling.
Fixed an error that prevented project users from adding customers to tasks. The system was incorrectly trying to update partner information when a customer was assigned, causing an access restriction error. This fix allows project team members to properly assign customers to tasks without encountering permission issues.
Original PR description
Steps to Reproduce: - 1. Log in with a user having only Project > User access. 2. Create a new task in project. 3. Add a customer on the task. 4. Access error is raised. Issue: - - Project users could not create a task with a customer. - An access error appeared during task creation. Cause: - - When a customer was added to the task, the partner_phone inverse method was triggered. - This method attempted to write on the partner record. Solution: - - Added a check before writing to avoid unnecessary writes. - Used sudo() to update the partner phone securely. - Added view-level restriction using base.group_partner_manager to control who can edit the phone number. task-5039657 Forward-Port-Of: odoo/odoo#256921 Forward-Port-Of: odoo/odoo#252406
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 corrects a configuration issue where branch companies using their parent company's VAT for PEPPOL registration were incorrectly shown a participation role setting. Since branches can only send documents (not receive), this setting is now hidden from the configuration 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 Odoo. Users can now click on date column headers in grouped views (like the Deferred Entries list) to sort the data, which was broken in a recent update. This improves the usability of financial reporting and data management 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 prevents the express checkout option (Apple Pay, Google Pay) from appearing when customers have gelato products in their cart. Gelato requires email and street address information to calculate shipping costs, which express checkout doesn't provide upfront. This resolves errors that customers were experiencing when trying to use express payment methods with gelato orders.
Original PR description
Issue: --- Public users get error using Apple/Google pay with gelato. Steps to reproduce: --- 1- Setup gelato and stripe express checkout. 2- Using phone, in incognito mode, add a gelato product to cart. 3- Try express checkout. Cause: --- This is because email and street is not present in express checkout. While gelato needs these info to generate calculate shipping cost. Fix: --- We can prevent the express checkout to be shown in gelato orders. opw-5904177 Forward-Port-Of: odoo/odoo#250443
This update resolves a critical issue where invoice delivery notifications (webhooks) were being blocked with access errors. When one user sends an invoice to another, the system now properly handles the notification delivery without permission failures, ensuring invoices are reliably transmitted between accounts.
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
Users can now successfully search for archived accounts by their account code. Previously, when filtering for inactive accounts and searching by code, the system would not display the archived account even though it matched the search criteria. This fix ensures that the account code search works correctly regardless of whether an account is active or archived.
Original PR description
# How to reproduce - Go to the chart of account - Archive any record (e.g. Code 101401) - Search with the filters : - Inactive Accounts - Account: 101401 (the code of the record) # The problem The…
# How to reproduce
- Go to the chart of account
- Archive any record (e.g. Code 101401)
- Search with the filters :
- Inactive Accounts
- Account: 101401 (the code of the record)
# The problem
The record that we searched for is not shown
# Cause
The domain for the "Account" filter is the following : https://github.com/odoo/odoo/blob/87c5f562e32ffb58359cf068124e03ead1a5859c/addons/account/views/account_account_views.xml#L147
And this is the domain for "Inactive Accounts":
https://github.com/odoo/odoo/blob/87c5f562e32ffb58359cf068124e03ead1a5859c/addons/account/views/account_account_views.xml#L159
This is correct and the search should return what we wanted, but the code's search is overriden by:
https://github.com/odoo/odoo/blob/87c5f562e32ffb58359cf068124e03ead1a5859c/addons/account/models/account_account.py#L383-L384
And the search with the `code_store` domain only explicitely looks for accounts that are active, so our "[('active', '=', False)]" is essentialy ignored
This is fixed in 19.1 because this commit (https://github.com/odoo/odoo/commit/de959adf7c806e09864b52fec78d981e66804280) replaced the custom search by a `compute_sql`
# Proposed solution
We change the search with the `code_store` to look for records that are both active and inactive, since the active value will be handled by the parent search
opw-6059404
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#256060This 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 update improves the certificate upload experience by removing unnecessary warning messages when users haven't set a password. The system now only validates the password when it's actually required during the save process, reducing confusing alerts and making the user experience smoother.
Original PR description
Before the change, when the user uploads a file, Odoo automatically shown a warning message saying that the content of the file or the password are incorrect. Now the system does not show the warning when a password is not set and checks if the password is set when saving task-6036219 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256759 Forward-Port-Of: odoo/odoo#253834
This fix resolves an issue where users couldn't close popup windows by pressing the Escape key when the popup contained no clickable buttons or links. The problem occurred because the focus was being set on the wrong element, preventing the browser's built-in close functionality from working. Now popups will consistently close with the Escape key regardless of their content.
Original PR description
Steps to reproduce: =================== - Add a Popup snippet to a page - Remove all links/buttons inside the popup - Save and wait for the popup to appear - Press ESC -> Nothing happens. Cause:…
Steps to reproduce:
===================
- Add a Popup snippet to a page
- Remove all links/buttons inside the popup
- Save and wait for the popup to appear
- Press ESC
-> Nothing happens.
Cause:
======
https://github.com/odoo/odoo/blob/a922c31fa7ccd1107b31287ab1f75697fae874f8/addons/website/static/src/snippets/s_popup/000.js#L219-L226 when the popup contains no tabbable elements, `this.el.focus()` was called. `this.el` refers to the `.s_popup` div, not the `.modal` element that Bootstrap monitors for keyboard events. As a result, the ESC keydown event never reached Bootstrap's handler and the modal stayed open.
When focusable elements (links, buttons) were present, `tabableEls[0].focus()` correctly focused an element inside `.modal`, so ESC worked fine in that case.
Solution:
=========
Replace `this.el.focus()` with `this.el.querySelector(".modal").focus()` so focus lands on the `.modal` element allowing Bootstrap's built-in ESC handler to fire correctly in all cases
opw-5891054
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#254284
Forward-Port-Of: odoo/odoo#250050This fix ensures that archived accounts are properly checked when creating the unaffected earnings account, preventing validation errors during system upgrades. Previously, the system would fail when an archived account had the same code as the new unaffected earnings account, particularly affecting users upgrading with the Saudi Arabia localization module installed.
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 a rare issue that prevented purchase orders from being confirmed due to an outdated field reference in the system. After a previous update renamed a field from 'product_uom' to 'product_uom_id', some code was not updated accordingly, causing errors when confirming orders. This patch corrects the field reference to ensure purchase orders can be confirmed without interruption.
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 update fixes an error that occurred when users tried to view custom snippets based on map components in the website editor. The issue happened because custom snippets created from disabled base snippets would fail to load. The fix prevents these problematic custom snippets from appearing, and also clarifies the names of the Map and Google Map snippets to reduce user confusion when both are visible in developer mode.
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#255704 Forward-Port-Of: odoo/odoo#250236
The Bluetooth caliper driver was sending measurement readings without a success status flag, causing the system to incorrectly show disconnection warnings even when measurements were read successfully. This fix ensures the driver properly marks measurements as successful, eliminating false disconnection alerts.
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
This update fixes a validation issue in the payment demo module to ensure provider configurations are properly checked. The fix prevents potential errors when processing payments by validating that the payment provider is correctly configured before use.
Original PR description
opw-3097856 Forward-Port-Of: odoo/odoo#256362
Mozambique users were seeing the incorrect Brazilian tax ID label "CPF/CNPJ" on their sales orders and invoices instead of the correct Mozambican label "NUIT". This fix adds the proper tax ID label for Mozambique so users now 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 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 promotional codes is active, allowing customers to continue applying discount codes without interruption.
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#256438 Forward-Port-Of: odoo/odoo#252518
This fix resolves an issue where importing sales and purchase orders with line-level charges (allowances and surcharges) would fail. The system now correctly processes quantity and tax information for these special line items, ensuring orders with complex charge structures can be imported successfully without errors.
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 corrects an issue where loyalty programs were incorrectly matching and accumulating points when price list functionality was disabled. Previously, disabled price lists were still being retained in the system, causing loyalty programs restricted to specific price lists to continue matching incorrectly. This update ensures loyalty programs behave as expected regardless of price list settings.
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
This fix ensures that guest customer accounts are only archived when automatic invoicing is enabled, and only after the invoice has been successfully sent. Previously, guests were archived immediately after order confirmation, which caused issues when manually sending invoices as the recipient field would be empty. This change also ensures company partners are properly archived along with guest contacts.
Original PR description
Before this fix, when automatic invoicing was disabled, manually sending an invoice by email resulted in an empty "Send To" field because the guest contact had already been archived. To prevent this issue, guest archiving is now triggered only when automatic invoicing is enabled. Additionally, to avoid problems with email delivery, the guest is archived only after the invoice has been sent. This ensures that the email generation process sees the guest as active. If the guest were archived immediately after the Sales Order confirmation, the email generation logic in `mail_thread.py` would skip the archived partner (`pdata['active'] is False`), preventing the invoice email from being sent.
This fix resolves an issue where duplicate "Replace by Attendance" buttons appeared when employees had multiple work entries of the same type on different days. The problem caused the system to crash when users clicked on calendar cells. The fix removes duplicate work entry types from the button list to ensure a clean, functional calendar experience.
Original PR description
### Steps to reproduce: - Download Payroll app - From the top bar 'Employees' > 'Employees', create a new employee - Select the created employee > click 'Work Entries' smart button, add 2 Attendance…
### Steps to reproduce: - Download Payroll app - From the top bar 'Employees' > 'Employees', create a new employee - Select the created employee > click 'Work Entries' smart button, add 2 Attendance work entries on different days, with different creation days (either wait 24h between creations, or adjust one create_date in DB) - Click on any day, you'll find the "Replace by Attendance" smart button replicated > If you activate debug mode and click on any cell > **UncaughtPromiseError > OwlError** ### Cause of issue: https://github.com/odoo/odoo/blob/72be98d705e225f663b65e289e11d0b8642ec6f8/addons/hr_work_entry/static/src/views/work_entry_calendar/work_entry_calendar_model.js#L30-L58 `formattedReadGroup` is called with both `work_entry_type_id` and `create_date:day`. If the user has created several work entries of the same type on different days, we would get multiple group results having the same `work_entry_type_id`. These duplicated records later produce an Owl crash because the button list uses `t-key="workEntry.id"`. https://github.com/odoo/odoo/blob/72be98d705e225f663b65e289e11d0b8642ec6f8/addons/hr_work_entry/static/src/views/work_entry_calendar/work_entry_multi_selection_buttons.xml#L16-L17 ### Fix: Since the goal of the above method is to extract the favorite work entries to later use in smart buttons and `userFavoritesWorkEntriesIds.map((r) => r.work_entry_type_id?.[0]).filter(Boolean)` extracts all the entries' `work_entry_type_id` (including duplicates), the easiest way to get rid of these duplicates is to create a `Set`. opw-5953671 Forward-Port-Of: odoo/odoo#252478 Note about v19.1: Since the bug isn't present in this version, we'll only merge the test.