Daily updates from Odoo
Friday, July 10, 2026
46 changes · saas-19.1
Security fixes and vulnerability patches
This change strengthens protection for database API keys by preventing them from being read through normal application access and hiding real key values in the interface. It reduces the risk of sensitive credentials being leaked accidentally or through bypassed access controls.
Original PR description
The aim of this commit is to harden the security of the `database_api_key` field. Before this commit: The field could be retrieved through the orm and could be leaked if the access rights were bypassed. A streamer pasting the key in the field could also leak his api key by mistake. After this commit: The only way to access the field is through direct SQL access. The api key isn't shown anymore in the UI: - The UI doesn't receive the key from the backend: it receives dummy **** - The field in the form view display dots instead of any char to prevent leaking the key by mistake. Task-id: None Forward-Port-Of: odoo/enterprise#122163
New functionality added to Odoo
Odoo now supports WhatsApp business-scoped user IDs, allowing businesses to keep contacting customers even when WhatsApp does not share their phone number. It also stores WhatsApp's normalized phone identifier to improve contact matching across different number formats.
Original PR description
Add support for whatsapp business-scoped user ids as outline in the [documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/business-scoped-user-ids) for their introduction this June. This effectively adds a table mapping BSUID to contacts to enable contacting users who contact the business directly, as the business will now not necessarily be provided with their number. Additionally the “whatsapp id”, i.e. the canonical form of the phone number as stored in whatsapp, is stored to help better match contacts regardless of formatting details in odoo and whatsapp. task-5476552 Forward-Port-Of: odoo/enterprise#117782
[ADD] l10n_ge: add Georgian Chart of Accounts - This commit adds the Georgian accounting localization, including the chart of accounts, taxes, fiscal positions, tax groups, and VAT report required for standard accounting and tax reporting flows - It provides support for domestic VAT, reverse charge VAT, and the Georgian VAT declaration report. taskID-3927928 related PR (from saas-19.3 to master) - https://github.com/odoo/odoo/pull/263765 Forward-Port-Of: odoo/odoo#263452
Original PR description
[ADD] l10n_ge: add Georgian Chart of Accounts - This commit adds the Georgian accounting localization, including the chart of accounts, taxes, fiscal positions, tax groups, and VAT report required for standard accounting and tax reporting flows - It provides support for domestic VAT, reverse charge VAT, and the Georgian VAT declaration report. taskID-3927928 related PR (from saas-19.3 to master) - https://github.com/odoo/odoo/pull/263765 Forward-Port-Of: odoo/odoo#263452
Enhancements to existing features
Attachment deletion is now much faster for Chilean electronic invoicing and stock documents. This reduces delays for users and background operations on databases with large volumes of accounting moves or stock transfers.
Original PR description
## The problem Deleting attachments checks foreign key triggers. Lookups in `account_move` and `stock_picking` tables for `ir_attachment` related fields coming from `l10n_cl_edi` overrides were slow due to missing indexes. ## The solution Added needed indexes to optimize triggers' lookups. ## Benchmark Time benchmark (deleting attachments from a customer database with 224K account moves and 204K stock pickings): |# of rows|Time (Before)|Time (After)| |----------|--------------|-------------| 100 | 29s | 16ms 1000 | 285s | 300ms OPW-6331845 Forward-Port-Of: odoo/enterprise#123350 Forward-Port-Of: odoo/enterprise#123252
Database records can now show the status of the Know Your Client process as a KPI. This helps teams quickly see customer verification progress directly from database information, improving monitoring and follow-up.
Original PR description
Add a new type kyc_status to display the status of the Know Your Client procedure in the databases. Task-id: [6348952](https://www.odoo.com/odoo/project.task/6348952) Forward-Port-Of: odoo/enterprise#122510
Following recent updates to the base `pos.printer` architecture in the point_of_sale module, the iMin driver configuration must be adapted to maintain compatibility and ensure seamless integration. This commit backports the alignment logic and structure originally introduced in saas-19.3. Previously, iMin configuration lived inside the general POS settings overrides. To align with the updated base class interface and prevent tracebacks or broken flows, the driver's configuration logic is n
Original PR description
Following recent updates to the base `pos.printer` architecture in the point_of_sale module, the iMin driver configuration must be adapted to maintain compatibility and ensure seamless integration. This commit backports the alignment logic and structure originally introduced in saas-19.3. Previously, iMin configuration lived inside the general POS settings overrides. To align with the updated base class interface and prevent tracebacks or broken flows, the driver's configuration logic is now migrated directly into the native `pos.printer` model ecosystem. This adaptation includes: - Moving the configuration views and logic to inherit from `pos.printer`. - Restricting iMin devices strictly to receipt printing via a new constraint. - Adding a 3-second timeout to the WebSocket availability check to comply with the base class's expectations for non-blocking status checks. - Updating backend testing support by patching `TestEPos`. opw-6218933
This update introduces a manual process for Know Your Customer (KYC) verification within the PEPPOL account setup in Odoo. Previously, this process was automated. Now, administrators can complete the necessary KYC documentation directly within Odoo, ensuring compliance with PEPPOL regulations and simplifying the account onboarding experience. This change improves the user experience and streamlines the account setup process for our PEPPOL customers.
Original PR description
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#275371
Resolved issues and error corrections
Subscription products that allow one-time purchases now correctly show the original price with a strikethrough next to the Buy Once price. This makes discounts or price comparisons clearer for shoppers and helps avoid confusion on product pages.
Original PR description
Version - saas-19.1 Steps to reproduce: - Enable 'Accept One Time Sale' on a subscription product - Open the product page on the website Issue: For subscription products with one time sale enabled, the original price was not shown as a strikethrough next to the Buy Once price. Fix: - Captured and exposed the original price to the template before it gets overwritten during subscription price processing - Added the missing strikethrough element to the Buy Once section of the product page Task ID - 6260207
This fixes an issue where status log messages for French reports could fail to display properly for accepted or rejected statuses. The correction ensures these messages render as intended, helping users understand report processing outcomes clearly.
Original PR description
A mismatch between error titles and status logs was introduced in 18.0. Markup wasn't added to the status logs, leading to a type mismatch (Markup + str) when displaying errors for 'accepted' or 'rejected' statuses. As a result, the logs were not interpreted as HTML. This commit ensures Markup is applied to each element to guarantee coherence and proper rendering. backport of 5113752 task-6053842 Forward-Port-Of: odoo/enterprise#123812 Forward-Port-Of: odoo/enterprise#123250
The barcode app now correctly respects operation settings that disable adding extra products. After all reserved items are scanned, users can no longer add or scan unreserved products on planned transfers where that option is turned off, helping maintain inventory process controls.
Original PR description
# How to reproduce - Go to Inventory > Settings > Operation Types - Pick any Operation and disable "Allow extra product" - Create a picking for that operation type with atleast one product and click…
# How to reproduce - Go to Inventory > Settings > Operation Types - Pick any Operation and disable "Allow extra product" - Create a picking for that operation type with atleast one product and click on "Mark as Todo" - Go to the Barcode app and find the created picking - Scan all the reserved products - Exit the picking and re-enter # The problem The "Add Product" button is displayed and you can scan unreserved products even tough you sould not be allowed to # Cause of the issue The problem stems from the fact that even with "Allow extra product" disabled, we still allow to add unreserved products for immediate transfers (created directly in the barcode app). The issue is that we don't really have a way to distinguish immediate transfers from plannified ones made in the Inventory app. So we try to guess using the `_useReservation` attribute (If it is false, we allow additional products). `_useReservation` is computed as follows : if any move lines from the inital state is not yet picked, set it to true : https://github.com/odoo/enterprise/blob/ca4b369e4fc9f4655574cf1ca71c81faaadc3e88/stock_barcode/static/src/models/barcode_picking_model.js#L43 So in our case, once all the reserved products are scanned, all the initial move lines are picked and our guessing fails. # Proposed Solution Since immediate transfers are never validated and stays in draft mode, guess using the state of the current picking in addition to `useReservation` opw-6231238 Forward-Port-Of: odoo/enterprise#118378
Invoices for partners with foreign EU VAT numbers are now placed in the correct Czech VAT control statement section. This prevents non-domestic transactions from being incorrectly grouped with domestic VAT entries, improving tax reporting accuracy.
Original PR description
With l10n_cz company: - Create an invoice for a partner with a foreign vat (EU) with an amount greater than 10000 CZ and a 21% tax. In the vat control statement of the tax report, the move is classified under A4. But the section A4 should only contain move with domestic vat opw-6268506 Forward-Port-Of: odoo/enterprise#120002
Audit reports now update the number of invalid records when a check is reviewed and no longer finds issues. This prevents users from seeing outdated anomaly counts after a check has been successfully cleared.
Original PR description
Problem: Sometimes after an audit check passes (gets reviewed successfully), the count of invalid records in the audit report is not updated. Steps to reproduce: 1. Add a check for an audit cycle 2. Make sure the check's domain is satisified by at least one record 3. Check the audit report and see the check you added 4. The check status should show an anomaly and the count of invalid records will be greater than 0 5. Now, edit the check so that the domain is not satisfied by any record 6. Check the audit report again and see the check you edited 7. The check status should show "Reviewed" but the count of invalid records will still be greater than 0, which is not correct Cause: When updating the status of an audit check, the count of invalid records is not updated, only the status gets updated. opw-6264177 Forward-Port-Of: odoo/enterprise#119227
Fixed an issue where expanding a Knowledge article in the sidebar could show only favorited child articles while hiding the rest. Users can now reliably see all child articles without needing to reload, improving navigation in Knowledge workspaces.
Original PR description
The sidebar always loads the user's favorite articles along with the visible ones, so a favorited article is shown as a root of the favorite tree. When that favorite is also a child of a folded…
The sidebar always loads the user's favorite articles along with the visible ones, so a favorited article is shown as a root of the favorite tree. When that favorite is also a child of a folded article, it gets added to its parent's child_ids in the main tree, even though the parent's other children were not fetched. A folded article only gets its favorited children back from get_sidebar_articles, not its whole child set. When the parent is then unfolded, unfold() only read the children from the database when child_ids was empty. The favorited child already filled child_ids, so the call was skipped and the remaining children stayed hidden until the next reload. unfold() now uses a new children_loaded flag instead of the length of child_ids to decide whether to fetch the children. The flag is set once an article's whole child set is loaded: in loadChildren(), and in loadArticles() for the articles that were unfolded, since those come back with all their children. loadChildren() also rebuilds child_ids from the search result so a favorite already loaded is not added twice. The fix lives in the sidebar component because the partial child_ids only exists on the frontend, get_sidebar_articles already returns the right records. Steps to reproduce: 1. Open the Knowledge app 2. Create an article with two child articles 3. Add one of the two children to your favorites with the star icon 4. Open another article that is not under that parent 5. Fold the parent article in the sidebar, then refresh the page 6. Expand the parent article => only the favorited child is shown under the parent, the other child is missing Ticket [link](https://www.odoo.com/odoo/project.task/6186466) opw-6186466 Forward-Port-Of: odoo/enterprise#118804
Fixes an issue that could block Kenyan POS refund validation with an error when the refund and original sale were processed together. Refunds and batches of offline orders are now handled correctly for eTIMS posting, helping cashiers complete refunds and sync orders smoothly.
Original PR description
Steps to reproduce: 1. Install `l10n_ke_edi_oscu_pos`, set company to Kenya. 2. Sell and validate an order. 3. Refund it from the POS and validate the refund order. Issue: - A traceback is raised…
Steps to reproduce: 1. Install `l10n_ke_edi_oscu_pos`, set company to Kenya. 2. Sell and validate an order. 3. Refund it from the POS and validate the refund order. Issue: - A traceback is raised when validating the refund: `ValueError: Expected singleton: pos.order(<refund>, <original>)` raised in `get_l10n_ke_edi_oscu_pos_data`. Cause: - When syncing a refund, `sync_from_ui` returns both the new refund order and the original refunded order. `waitForPushOrder` forces post-processing for every Kenyan order in that list, so `beforePostPushOrderResolve` receives both ids in `order_server_ids` and forwards them as-is to `action_post_order` and `get_l10n_ke_edi_oscu_pos_data`, both of which expect a single record. `action_post_order` fails the same way, but its error was silently swallowed by the surrounding try/catch, letting the traceback surface only on the second call. - The same multi-id list is also produced whenever several orders created offline get synced together once back online. Solution: - `get_l10n_ke_edi_oscu_pos_data` is only needed for the receipt of the order being validated, so call it with `order.id` instead of the full `order_server_ids` list. - Replace the `action_post_order` call with `action_post_selected_orders`, which posts each order individually and skips ones already sent to eTIMS, correctly handling both the refund case (original order is already `sent`) and the offline multi-order sync case. opw-6364221 Forward-Port-Of: odoo/enterprise#123043
Appointment blocks using the picture or list layout now show prices according to the website's tax display setting. This prevents customers from seeing tax-excluded prices when the website is configured to show tax-included pricing.
Original PR description
When the `appointments_template_picture` and `appointments_template_list` templates were added to `website_appointment_account_payment` in 19.0+, the corresponding overrides in `website_appointment_sale` were not added. This caused the picture and list appointment blocks to display prices using `product_lst_price` (always tax-excluded), ignoring the website's tax display setting (`show_line_subtotals_tax_selection`). The cards template already had a proper override using `_get_combination_info()`, which correctly handles everything. Steps to reproduce: 1. Go to Website > Configuration > Settings > enable "Tax Included" 2. Create an appointment type with a product that has taxes 3. Edit website page > add "Appointments" snippet > select "Picture" or "List" layout => price shown is tax-excluded Ticket [link](https://www.odoo.com/odoo/project.task/5799252) opw-5799252 Forward-Port-Of: odoo/enterprise#106643
Duplicating certain Sign templates with multiple documents, signers, and fields could fail because the system tried to reuse already-processed signer information incorrectly. This fix skips signer records that have already been handled, making template duplication reliable again.
Original PR description
Issue: This [loop](https://github.com/odoo-dev/enterprise/blob/55bb2cc570451361701d53583f019ed832a5e5d3/sign/models/sign_item.py#L59-L63) runs multiple times with the same approvers(sign.item.role), but doesn't take into account the already 'seen map' inside the base copy function for batching. If they are already seen they will return a non-iterable [None]. To replicate: 1) Sign -> Template -> upload PDF 2) Go into the template 3) Add 2 Documents, with 2 signers and multiple fields on both documents 4) Save -> gear Icon -> make into template 5) Go back to the list view of templates 6) Select the template -> Gear Icon -> Duplicate Fix: add an already seen check to skip if already seen. opw-6352408 Forward-Port-Of: odoo/enterprise#122667
The Argentine VAT Book ZIP export no longer fails when invoices involve foreign providers using a Foreign ID. This helps accounting teams generate the required VAT reports without manual workarounds or blocked exports.
Original PR description
Steps to reproduce: - Create a partner with: - State: Ireland - Identification Number: Foreign ID 55000004153 - ARCA Responsibility Type: Proveedor del Exterior - Create an invoice for the partner - Accounting > Reporting > Tax report - Select Report: VAT Book (AR), Tax Type: Sales - Click on gear icon > VAT Book (ZIP) Issue: Action will be blocked with error "No VAT configured for partner [58] <partner>" Analysis: Partners with ARCA responsibility type 'Proveedor del Exterior' (code 8) and a ForeignID identification type, causes a UserError when exporting the VAT Book (ZIP). Code 8 (foreign provider) is the purchase-side counterpart of code 9 (foreign customer), which already fell back to the country-level VAT. Extend the existing fallback branch to cover both codes. opw-6316008 Forward-Port-Of: odoo/enterprise#123506
**Steps to reproduce:** - Install Accounting and l10n_ar_withholding - Switch to an Argentinian company (e.g. (AR) Responsable Inscripto) - Create a 0% Payment Withholding tax: * Tax Type: Customer Payment Withholding * Amount: 0.00 % * Add an account for the tax distribution lines - Create an invoice with a tax - Confirm the invoice - Pay the invoice: * Withholdings: - Add a line with the created 0% Payment Withholding tax - Add a line with another Payment
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_ar_withholding - Switch to an Argentinian company (e.g. (AR) Responsable Inscripto) - Create a 0% Payment Withholding tax: * Tax Type: Customer…
**Steps to reproduce:**
- Install Accounting and l10n_ar_withholding
- Switch to an Argentinian company (e.g. (AR) Responsable Inscripto)
- Create a 0% Payment Withholding tax:
* Tax Type: Customer Payment Withholding
* Amount: 0.00 %
* Add an account for the tax distribution lines
- Create an invoice with a tax
- Confirm the invoice
- Pay the invoice:
* Withholdings:
- Add a line with the created 0% Payment Withholding tax
- Add a line with another Payment Withholding tax
- Create Payment
- Go to the payment
**Issue 1:**
When clicking on the first withholding line, a JS error is raised due to a missing index (i.e. currency_id).
**Cause 1:**
One of the fields has an aggregate sum function applied on it (i.e. amount_currency).
As it is a monetary field, the corresponding currency field is required in the view.
**Issue 2:**
When resetting the payment to draft, the withholding line with the 0% tax is deleted.
As the withholding table is not editable, it is not possible to add the line again.
**Cause 2:**
When the payment is reset to draft, the state of the associated journal entry is also set to draft and a "_sync_dynamic_lines" is triggered, which remove tax lines having a zero amount during the process.
**Solution 2:**
Keep all the lines with a Customer Payment Withholding tax as it is not possible to add a withholding line in the payment afterwards.
opw-6298058
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#274604
Forward-Port-Of: odoo/odoo#271555…nding When cash rounding is enabled with "Only for cash payment methods", an order partially paid in cash and completed with an online payment could neither request the correct online amount nor be marked as paid. Steps to reproduce: - Enable cash rounding (e.g. 0.05, HALF-UP) with "Only for cash payment methods" - Create an order with a total of 15.28 - Add a cash payment of 10.00, then an online payment for the remainder The frontend requests 5.28 for the online payment, but as so
Original PR description
…nding When cash rounding is enabled with "Only for cash payment methods", an order partially paid in cash and completed with an online payment could neither request the correct online amount nor be…
…nding When cash rounding is enabled with "Only for cash payment methods", an order partially paid in cash and completed with an online payment could neither request the correct online amount nor be marked as paid. Steps to reproduce: - Enable cash rounding (e.g. 0.05, HALF-UP) with "Only for cash payment methods" - Create an order with a total of 15.28 - Add a cash payment of 10.00, then an online payment for the remainder The frontend requests 5.28 for the online payment, but as soon as the order contained a cash payment the server rounded the whole order total: get_and_set_online_payments_data() returned an unpaid amount of 5.30 (15.30 - 10.00), so the validation failed with "Invalid online payments". Even once the online payment of 5.28 was processed, the order remained stuck in draft with the money captured: _is_pos_order_paid() compared the paid amount (15.28) against the rounded total (15.30). Only the part of the order actually settled in cash must be rounded: non-cash payments (card, online, ...) always pay their exact share. - get_amount_unpaid() now returns the exact residual of the order when the rounding only applies to cash payment methods. - _get_rounded_amount() now only rounds the amount not covered by non-cash payments, resolving its old TODO. Cash-only orders and orders where the cash payment settles the rounded remainder are unaffected. opw-6314690 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275305
When a POS line comes from a sale order, its invoice line name is overridden with the source sale order line's name. When a down payment is invoiced directly from the POS, the invoice is generated before the down payment POS line is linked to its sale order line, so sale_order_line_id is still empty and the override resolved to an empty recordset, setting the invoice line name to False. Only override the name when a sale order line is actually set, so the down payment line keeps its own name.
Original PR description
When a POS line comes from a sale order, its invoice line name is overridden with the source sale order line's name. When a down payment is invoiced directly from the POS, the invoice is generated before the down payment POS line is linked to its sale order line, so sale_order_line_id is still empty and the override resolved to an empty recordset, setting the invoice line name to False. Only override the name when a sale order line is actually set, so the down payment line keeps its own name. opw-6305649 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274000
Since [1] elements within the link preview can be focused. However, when pressing tab an error is raised. This commit prevents this error from happening. [1]: https://github.com/odoo/odoo/commit/34db19f4a2b42d7e41205d7d793f5b3f408c19af task-6366337 Forward-Port-Of: odoo/odoo#275149 Forward-Port-Of: odoo/odoo#274682
Original PR description
Since [1] elements within the link preview can be focused. However, when pressing tab an error is raised. This commit prevents this error from happening. [1]: https://github.com/odoo/odoo/commit/34db19f4a2b42d7e41205d7d793f5b3f408c19af task-6366337 Forward-Port-Of: odoo/odoo#275149 Forward-Port-Of: odoo/odoo#274682
**Steps to reproduce:** - Go to Contact app - Open any record - Press "Space" key - Traceback: `Cannot read properties of undefined (reading 'groupId')` **Issue:** `quickCreateState` props is undefined (as it is optional). **Fix:** Add check to safely handle such cases. [introduced by] https://github.com/odoo/odoo/commit/22c07c7dcb2a93d9ebef5a83e48aa3d252128519 opw-6377425
Original PR description
**Steps to reproduce:** - Go to Contact app - Open any record - Press "Space" key - Traceback: `Cannot read properties of undefined (reading 'groupId')` **Issue:** `quickCreateState` props is undefined (as it is optional). **Fix:** Add check to safely handle such cases. [introduced by] https://github.com/odoo/odoo/commit/22c07c7dcb2a93d9ebef5a83e48aa3d252128519 opw-6377425
Steps to reproduce: - Open Chrome. - Set the browser zoom below or above 100%. - Edit a website page. - Hover a resize or padding handle in the overlay. => A white line appears in the middle of the handle. Before this commit, overlay handles changed their inner outline color on hover. With Chrome zoom levels different from 100%, this could leave a white line visible in the middle of the handle. After this commit, overlay handles change their background color on hover and use a consiste
Original PR description
Steps to reproduce: - Open Chrome. - Set the browser zoom below or above 100%. - Edit a website page. - Hover a resize or padding handle in the overlay. => A white line appears in the middle of the handle. Before this commit, overlay handles changed their inner outline color on hover. With Chrome zoom levels different from 100%, this could leave a white line visible in the middle of the handle. After this commit, overlay handles change their background color on hover and use a consistent inner outline width, so no white line is visible. task-6048647 Forward-Port-Of: odoo/odoo#273722
Steps to reproduce ------------------- - Install sale_project, accountant and project_timesheet_forecast_sale modules; - Activate analytic accounting in the settings; - Add an outstanding account to the bank journal’s manual outgoing payment method; - Create a new billable project; - Open the top menu, add vendor bills and open it; - Create a new bill from there, it should use the project’s analytic distribution; - Confirm it and create a payment; - Open the payment’s journal entry, i
Original PR description
Steps to reproduce ------------------- - Install sale_project, accountant and project_timesheet_forecast_sale modules; - Activate analytic accounting in the settings; - Add an outstanding account to…
Steps to reproduce ------------------- - Install sale_project, accountant and project_timesheet_forecast_sale modules; - Activate analytic accounting in the settings; - Add an outstanding account to the bank journal’s manual outgoing payment method; - Create a new billable project; - Open the top menu, add vendor bills and open it; - Create a new bill from there, it should use the project’s analytic distribution; - Confirm it and create a payment; - Open the payment’s journal entry, it is using the analytic distribution too; Why is it happening -------------------- When opening a vendor bill from the project, the project_id is added to the account.move's context to use the correct analytic distribution when we create a bill. If we create a payment after accessing the bill from this route, the context is transfered to account.payment.register, and then to the payment's entry lines in the `_create_payments` method. Due to the `_compute_analytic_distribution` method, the project's distribution is used on the payment's entry. We propose to filter out payment lines in this compute method. opw-6329475 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275076
When we create a company with a EU VAT, we used to do 2 IAP call to verify the VAT number. One was on the create() and the other one on the write(). For performance reason and because the vies check service may limit ip address, the verification was already disable when importing files (in both create and write). This commit remove the compute on the create one (and keep the one on write), so that it only do 1 IAP call to verify the VAT. Task-6139346 Forward-Port-Of: odoo/odoo#275181
Original PR description
When we create a company with a EU VAT, we used to do 2 IAP call to verify the VAT number. One was on the create() and the other one on the write(). For performance reason and because the vies check service may limit ip address, the verification was already disable when importing files (in both create and write). This commit remove the compute on the create one (and keep the one on write), so that it only do 1 IAP call to verify the VAT. Task-6139346 Forward-Port-Of: odoo/odoo#275181 Forward-Port-Of: odoo/odoo#274644
# How to reproduce - Create a new product - Add a reordering rule to that product with : - Trigger : Auto - Min : > Forecast - Activate dev mode - Go to Seetings > Technical > Automation > Scheduled Actions - Find the "Procurement: run Scheduler" action & run it manually # The issue We get a traceback : psycopg2.errors.SerializationFailure: could not serialize access due to concurrent update # Cause In Odoo, we use an isolation level of "REPEATABLE READ" for transactions : htt
Original PR description
# How to reproduce - Create a new product - Add a reordering rule to that product with : - Trigger : Auto - Min : > Forecast - Activate dev mode - Go to Seetings > Technical > Automation > Scheduled…
# How to reproduce - Create a new product - Add a reordering rule to that product with : - Trigger : Auto - Min : > Forecast - Activate dev mode - Go to Seetings > Technical > Automation > Scheduled Actions - Find the "Procurement: run Scheduler" action & run it manually # The issue We get a traceback : psycopg2.errors.SerializationFailure: could not serialize access due to concurrent update # Cause In Odoo, we use an isolation level of "REPEATABLE READ" for transactions : https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/odoo/sql_db.py#L373 Even with that isolation level psql can throw a `SerializationFailure` if a transaction attempts to update a row that was modified by another transaction after the isolation snapshot was taken. ### Example that will raise an error : Session 1 ```SQL BEGIN ISOLATION LEVEL REPEATABLE READ; UPDATE accounts SET balance = balance - 100 WHERE id = 1; ``` Session 2 ```SQL BEGIN ISOLATION LEVEL REPEATABLE READ; UPDATE accounts SET balance = balance - 50 WHERE id = 1; COMMIT; ``` Back to Session 1 ```SQL COMMIT; ``` When running our action, we do this : https://github.com/odoo/odoo/blob/dff0835346f30fd1ef77260d94bcceeeab4d9051/addons/stock/models/stock_rule.py#L697-L703 Which correspond exactly to the first example : We first update some records with their compute Then `orderpoints.sudo()._procure_orderpoint_confirm(...)` creates a new transaction, update some rows & commits : https://github.com/odoo/odoo/blob/dff0835346f30fd1ef77260d94bcceeeab4d9051/addons/stock/models/stock_orderpoint.py#L716-L719 https://github.com/odoo/odoo/blob/dff0835346f30fd1ef77260d94bcceeeab4d9051/addons/stock/models/stock_orderpoint.py#L781-L783 Finally, we commit the original transaction with `_commit_progress(1)` # Proposed solution Inverse the order of `_commit_progress(1)` and `orderpoints.sudo()._procure_orderpoint_confirm(...)` so we commit the first transaction before starting the second one. opw-6261675 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268616
When opening a table that has no order, `setTable` recycles an existing empty floating order instead of creating a new one (to avoid leaving dangling blank orders behind). The filter only checked for the absence of a table, lines and finalized state, so it could grab any empty floating order, including one deliberately created for takeout or delivery. Steps to reproduce: - Open a restaurant POS with presets enabled (e.g. Dine in / Takeaway). - Cashier A creates a new floating order for a ph
Original PR description
When opening a table that has no order, `setTable` recycles an existing empty floating order instead of creating a new one (to avoid leaving dangling blank orders behind). The filter only checked for…
When opening a table that has no order, `setTable` recycles an existing empty floating order instead of creating a new one (to avoid leaving dangling blank orders behind). The filter only checked for the absence of a table, lines and finalized state, so it could grab any empty floating order, including one deliberately created for takeout or delivery. Steps to reproduce: - Open a restaurant POS with presets enabled (e.g. Dine in / Takeaway). - Cashier A creates a new floating order for a phone customer: selects the Takeaway preset with a future time slot, but has not added any product yet. - Meanwhile, cashier B opens an empty table from the floor screen. - => The takeout order is assigned to the table and becomes a dine-in order, losing its takeout context. Only recycle blank direct sale orders: skip orders that have a floating order name, a scheduled preset time or a preset different from the config default, as those were created on purpose. Tapping a table while on a blank dine-in scratch order still converts it as before. opw-6041750 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262573
\* : website, web_editor, html_editor Commit [1]: Steps to reproduce: replacing image stuck issue when deleted 1. Go to Website > Edit. 2. Add any picture snippet (e.g., Text-Image). 3. Click the 'Replace' button and upload an image. 4. Open the media dialog again and delete the uploaded image. 5. Click the 'Discard' button. 6. Try to save the changes. Issue: - The website gets stuck in the same position and does not allow saving. - In the Python terminal, a missing error warnin
Original PR description
\* : website, web_editor, html_editor Commit [1]: Steps to reproduce: replacing image stuck issue when deleted 1. Go to Website > Edit. 2. Add any picture snippet (e.g., Text-Image). 3. Click the…
\* : website, web_editor, html_editor Commit [1]: Steps to reproduce: replacing image stuck issue when deleted 1. Go to Website > Edit. 2. Add any picture snippet (e.g., Text-Image). 3. Click the 'Replace' button and upload an image. 4. Open the media dialog again and delete the uploaded image. 5. Click the 'Discard' button. 6. Try to save the changes. Issue: - The website gets stuck in the same position and does not allow saving. - In the Python terminal, a missing error warning appears because the image is deleted from both `ir.ui.view` and `ir.attachment`. Expected behaviour: - Saving should be allowed with a default image, that is similar to other images. This commit catch the warning response and replaces the deleted image, allowing the website to save changes without getting stuck. Commit [2]: resolve traceback when leaving edit mode via browser Steps to reproduce: 1. Go to Website > Edit. 2. Open the snippet modal and select any snippet. 3. Press the 'Back' button in your browser. 4. A dialog will appear asking to discard changes; click 'OK'. 5. A traceback error occurs, and an empty space appears in the editor. Issue: - Previously, a commit addressed a similar scenario, but that time the browser had an event listener bind on hashchange. - Now, that `hashchange` event of browser has been replaced with `popstate`, which triggers before the 'window' event listener. - As a result, the editor is left in an unstable state, causing a traceback error. Solution: - This commit ensures the 'window' event executes before the browser event. - It verifies if the editor is open and forces a `skipLoad`, preventing the `route_change` call in the browser. task-4570164 Forward-Port-Of: odoo/odoo#275150 Forward-Port-Of: odoo/odoo#199193
The native `warnings.deprecated` decorator strictly requires a string literal as its first positional argument and cannot be applied as a bare decorator. This commit enforces the same type verification in the fallback implementation for Python < 3.13. Follow-up of odoo/odoo@42fcc766af0584ef720a1cee5beb7878cdd1a572 runbot-941402 Forward-Port-Of: odoo/odoo#275037
Original PR description
The native `warnings.deprecated` decorator strictly requires a string literal as its first positional argument and cannot be applied as a bare decorator. This commit enforces the same type verification in the fallback implementation for Python < 3.13. Follow-up of odoo/odoo@42fcc766af0584ef720a1cee5beb7878cdd1a572 runbot-941402 Forward-Port-Of: odoo/odoo#275037
Description of the issue/feature this PR addresses: When grouping datetime fields by hour, `read_group` formats the group display label using `hh:00 dd MMM`. In Babel/LDML formatting, `hh` represents a 12-hour clock. Since the format does not include an AM/PM marker, afternoon/evening hours are displayed ambiguously in grouped views. Current behavior before PR: A datetime value in the afternoon is grouped under a 12-hour label without AM/PM. For example, records around `13:50` are dis
Original PR description
Description of the issue/feature this PR addresses: When grouping datetime fields by hour, `read_group` formats the group display label using `hh:00 dd MMM`. In Babel/LDML formatting, `hh` represents…
Description of the issue/feature this PR addresses:
When grouping datetime fields by hour, `read_group` formats the group display label using `hh:00 dd MMM`.
In Babel/LDML formatting, `hh` represents a 12-hour clock. Since the format does not include an AM/PM marker, afternoon/evening hours are displayed ambiguously in grouped views.
Current behavior before PR:
A datetime value in the afternoon is grouped under a 12-hour label without AM/PM.
For example, records around `13:50` are displayed under:
01:00 20 Mar
Similarly, a datetime value around `16:20` may be grouped under:
04:00 26 Mar
This is ambiguous because the group header does not indicate whether the hour is AM or PM.
Example screenshot showing records around 13:xx grouped under `01:00`:
<img width="310" height="240" alt="image" src="https://github.com/user-attachments/assets/8768f2e8-9aaa-436b-af9f-40055a6032e9" />
Desired behavior after PR is merged:
Hour-based datetime group labels should be unambiguous.
The hour grouping format now uses `HH:00 dd MMM`, so grouped datetime labels render using a 24-hour clock.
For example:
13:00 20 Mar
16:00 26 Mar
This fixes the datetime hour grouping label shown in grouped list views and other `read_group` consumers.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#275219
Forward-Port-Of: odoo/odoo#274724The test_cache test failed a couple times on a timeout error, this is because the more modules are installed, the longer it takes to index them all and generate the json document. [runbot-240550](https://runbot.odoo.com/odoo/error/240550) Forward-Port-Of: odoo/odoo#274773
Original PR description
The test_cache test failed a couple times on a timeout error, this is because the more modules are installed, the longer it takes to index them all and generate the json document. [runbot-240550](https://runbot.odoo.com/odoo/error/240550) Forward-Port-Of: odoo/odoo#274773
Steps to reproduce: - Create a promotion program (e.g. "10% discount on your order", reward_point_mode "per order") and restrict its rule to a specific product A; leave the minimum quantity at 0 - Open a PoS session and add any other product B to the order Issue: The discount was applied even though the order contained none of the rule's valid products. Cause: In `pointsForPrograms`, a rule was only gated on its quantity and amount thresholds (`totalProductQty < rule.minimum_qty`), nev
Original PR description
Steps to reproduce: - Create a promotion program (e.g. "10% discount on your order", reward_point_mode "per order") and restrict its rule to a specific product A; leave the minimum quantity at 0 -…
Steps to reproduce: - Create a promotion program (e.g. "10% discount on your order", reward_point_mode "per order") and restrict its rule to a specific product A; leave the minimum quantity at 0 - Open a PoS session and add any other product B to the order Issue: The discount was applied even though the order contained none of the rule's valid products. Cause: In `pointsForPrograms`, a rule was only gated on its quantity and amount thresholds (`totalProductQty < rule.minimum_qty`), never on the actual presence of a valid product in the order. Program templates (promotion, promo_code, next_order_coupons) create rules with minimum_qty = 0, so a product-restricted rule passed with zero matching items and, in "order" point mode, granted its points unconditionally. The same hole existed in `_canGenerateRewards` for scanned coupon programs, where rules act as conditions. The backend does not have this issue: `_program_check_compute_points` in sale_loyalty skips any rule whose valid products are not present in the order. Fix: Mirror the backend behavior in the PoS frontend: skip a product-restricted rule in `pointsForPrograms` when no (non-reward) order line matches its valid products, and make `_canGenerateRewards` return false in the same situation. Gift card and eWallet flows are unaffected since their "money"/"unit" point modes already gave 0 points when the trigger product was absent. opw-6357241 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275073
When uploading a font file "FontName 123 Light.otf" the baseFontName needs to be quoted in the font-face CSS to be valid. Single font files parsing for the shortestNamedFont now also correctly keeps the weight for the targetFonts. Description of the issue/feature this PR addresses: Uploaded fonts with spaces in the name are not working. Current behavior before PR: When uploading a font with a space in the filename like "FontName 123 Light.otf" the css declaration in the attachement i
Original PR description
When uploading a font file "FontName 123 Light.otf" the baseFontName needs to be quoted in the font-face CSS to be valid. Single font files parsing for the shortestNamedFont now also correctly keeps…
When uploading a font file "FontName 123 Light.otf" the baseFontName needs to be quoted in the font-face CSS to be valid.
Single font files parsing for the shortestNamedFont now also correctly keeps the weight for the targetFonts.
Description of the issue/feature this PR addresses:
Uploaded fonts with spaces in the name are not working.
Current behavior before PR:
When uploading a font with a space in the filename like "FontName 123 Light.otf" the css declaration in the attachement is wrong and not working:
```css
@font-face {
font-family: FontName 123 Light;
font-style: normal;
font-weight: 400;
src: url("/web/content/1057/FontName 123 Light.otf");
}@font-face {
font-family: FontName 123 Light;
font-style: normal;
font-weight: 400;
src: url("/web/content/1057/FontName 123 Light.otf");
}
```
Desired behavior after PR is merged:
The font name is now correctly quoted and the font attributes are no longer overwritten for the shortestNameFont:
```css
@font-face {
font-family: "FontName 123 Light";
font-style: normal;
font-weight: 400;
src: url("/web/content/1057/FontName 123 Light.otf");
}@font-face {
font-family: "FontName 123 Light";
font-style: normal;
font-weight: 300;
src: url("/web/content/1057/FontName 123 Light.otf");
}
```
Info @wt-io-it
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#273534
Forward-Port-Of: odoo/odoo#268842In python-stdnum 2.0+, the upstream issue regarding the zeep Transport class timeout handling has been resolved arthurdejong/python-stdnum@6cbb9bc09c25fbda7a032521bc57b44e0ce18ec4), and the method signature for `get_soap_client` was updated to include the `verify` parameter. Applying our legacy monkey patch on python-stdnum >= 2.0 causes signature mismatch issues and is no longer necessary. This commit: - Restricts the `get_soap_client` monkey patch to run only for `python-stdnum < 2.0`.
Original PR description
In python-stdnum 2.0+, the upstream issue regarding the zeep Transport class timeout handling has been resolved arthurdejong/python-stdnum@6cbb9bc09c25fbda7a032521bc57b44e0ce18ec4), and the method signature for `get_soap_client` was updated to include the `verify` parameter. Applying our legacy monkey patch on python-stdnum >= 2.0 causes signature mismatch issues and is no longer necessary. This commit: - Restricts the `get_soap_client` monkey patch to run only for `python-stdnum < 2.0`. - Updates `requirements.txt` to use python-stdnum 2.2 for Python 3.14+ to ensure compatibility with Ubuntu Resolute. Forward-Port-Of: odoo/odoo#275360 Forward-Port-Of: odoo/odoo#275046
This update fixes an issue where numbers were not being formatted correctly for Portuguese (pt_PT) and Hindi (hi_IN languages). Number grouping, which separates large numbers into logical groups, has been adjusted to align with international standards – three digits for Western countries and two digits after the first three for India, improving readability and accuracy.
Original PR description
Currently the number grouping for Portuguese and Hindi is missing. Number grouping is used to separate long numbers in logical groups to make then easier to read. In Western countries, the grouping is usually done in groups of three digits (e.g. `1,000,000` instead of `1000000`), while in India, the grouping is done in groups of two digits after the first three digits (e.g. `10,00,000` instead of `1000000`). Source: https://www.unicode.org/cldr/charts/48/by_type/numbers.number_formatting_patterns.html#24a93b3d14ba17b2 All languages will be revised in a follow-up `master` PR. [task-6320391](https://www.odoo.com/odoo/project.task/6320391) Forward-Port-Of: odoo/odoo#275237 Forward-Port-Of: odoo/odoo#274443
This update resolves an issue where website builder option titles were missing translations, causing errors in the builder interface. The fix ensures that all titles are now correctly translated, improving the user experience and allowing for consistent branding across the website. This improves the website's appearance and functionality for customers.
Original PR description
Steps to reproduce: - Open the website editor. - Go to the Theme tab. - Inspect the Primary or Secondary color picker title. => The title prop is undefined. - Go to a product page with several product images. - Edit the carousel thumbnail position option. => The Left and Bottom button titles are undefined. Before this commit, some builder option titles were passed as OWL expressions instead of translated string props. After this commit, these titles use translated string props and are properly available to the builder components. task-6034856 Forward-Port-Of: odoo/odoo#275235
This update fixes an issue where credit notes renamed and sorted before invoices could incorrectly shift lot assignments on existing invoices. The change ensures that lot allocations remain stable after credit note modifications, preventing invoices from consuming the wrong lot. This improves accuracy in inventory tracking and reporting.
Original PR description
#### Issue: When a credit note is renamed so that it sorts before the related invoices, the lot assigned on invoice previews can become incorrect. Already posted invoices can appear to consume the…
#### Issue: When a credit note is renamed so that it sorts before the related invoices, the lot assigned on invoice previews can become incorrect. Already posted invoices can appear to consume the first lot again. Example: A sale order is delivered in 2 batches: 10 units from SN01, then 10 units from SN02. Invoice 1 correctly shows SN01 and Invoice 2 correctly shows SN02. If Invoice 1 is refunded, re-invoiced, and the credit note is then renamed so it sorts before the invoices, Invoice 2 can incorrectly switch back to SN01. #### Steps to reproduce: - Enable "Display Lots & Serial Numbers on Invoices". - Create a sale order for 20 units of a tracked product. - Deliver 10 units from the first lot/serial number and 10 units from a second one in a backorder. - Create and post 2 invoices, one for each delivery. - Create and post a credit note for the first invoice. - Create and post a new invoice for 10 units. - Reset the credit note to draft, rename it so that it sorts before the invoices, then repost it. - Check the lot previews on the invoices. #### Root Cause: _get_invoiced_lot_values() orders invoice lines with move_name, which is mutable, then computes the previously invoiced quantities from that order. When a refund is renamed so it sorts before the invoices, the set of "previous" invoice lines changes. On top of that, reversed invoices are filtered out too broadly, even when their reversing move should not yet impact the current invoice chronology. #### Fix: Order invoice lines with immutable move ids instead of move_name, and only ignore reversed invoices once their reversing move is also before the current invoice in the effective chronology. This keeps posted invoices stable while preserving the re-invoice behavior. opw-6110232 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264776
This update corrects a technical problem where orderpoint failure activities incorrectly attributed the action to a user instead of the system. This prevented proper logging and could cause access issues. The fix ensures that system activities are always authored by OdooBot, maintaining data integrity and security.
Original PR description
When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `Procurement Exception` and logs a warning activity on the product template. The…
When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `Procurement Exception` and logs a warning activity on the product template. The exception handler uses `.sudo().activity_schedule()`, which bypasses the write access restriction but leaves `env.uid` as the portal user. Therefore, the restricted portal user permanently becomes the `create_uid` (Author) of the activity. System exception activities should always be authored by the system (OdooBot), never by a portal or public user. This context leak corrupts the activity metadata by injecting an external user ID into internal backend logs. Chain `.with_user(SUPERUSER_ID)` to the `.sudo()` call in `stock_orderpoint.py` when scheduling the exception activity. This ensures the environment context is stable and the activity is authored by OdooBot, which transcends multi-company record rules. Steps to Reproduce on Runbot/Fresh Database on version 17.0: 1. Enable Multi-Company with Company A and Company B. Set Company B as the active company for the website. 2. Restrict the main Admin (Runbot) user strictly to Company A. 3. Create a Shared Product (Company field left blank). 4. Set a Reordering Rule (Orderpoint) for the product that is guaranteed to fail routing. 5. Navigate to the frontend website and sign up as a new user (this creates a Portal User in Company B). 6. As the newly signed-up Portal User, complete an eCommerce checkout for the shared product. 7. The checkout succeeds, but the backend triggers the orderpoint failure and logs the exception activity on the product template. 8. Check the chatter for this product: the `create_uid` is incorrectly set to the Portal User instead of OdooBot (1). 9. (In 19.0 Upgrade) Log in as the Admin user (set strictly to view Company A), navigate to the product, and the AccessError for reading will appear due to this leaked id. [opw-6253978](https://www.odoo.com/odoo/my-support-tasks/6253978?debug=assets) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275140 Forward-Port-Of: odoo/odoo#269395
This update removes a confusing message ('Connect your software...') from sales quotations that appeared in PDFs for customers with portal access. The change ensures all quotes are clean and professional, regardless of whether the customer uses the Odoo portal. This improves the customer experience and aligns with the standard portal button appearance.
Original PR description
Steps to reproduce: 1. Install Contacts and Sales 2. Open any of the contacts, click on the gear icon at the top and click on "Grant portal access" 3. Grant access to all contacts 4. Create a Sale Quotation for that contact and print it Issue: The sentence 'Connect your software... ' appears in the pdf when sending the quote to a contact who was portal access, while it does not appear if the contact does not have portal access Expected behavior: Should not appear regardless of whether the customer has a portal account or not since they have it appear as a smart button in their portal. opw-6308357 Forward-Port-Of: odoo/odoo#272893
This update fixes an issue where a process was unnecessarily triggered repeatedly, slowing down VAT processing for French businesses. The change streamlines the process by now initiating the update only when a specific date is set, improving overall system performance and efficiency. This ensures smoother and faster VAT handling.
Original PR description
In previous fix https://github.com/odoo/odoo/commit/29b24a17a40d0f45a0e459cda68ca53b7d40075e we called _force_update_l10n_fr_f10_moves when the value of _compute_l10n_fr_pdp_flow_10_start_date changed as if it was stored, whitch it's not, calling the method each time the compute was triggered. Now _force_update_l10n_fr_f10_moves is run when l10n_fr_pdp_annuaire_start_date is set. Forward-Port-Of: odoo/odoo#275019
This update resolves an issue where attempting to send IT invoices to the tax agency caused an error in version 19.0. The fix ensures that users are guided to delete the PDF attachment before sending, mirroring the behavior in previous versions and preventing the error.
Original PR description
**Steps to reproduce:** - Install the `l10n_it_edi` module and switch to an IT Company. - Create and confirm an invoice for a non-Italian customer. - Send the invoice, making sure that only `by…
**Steps to reproduce:** - Install the `l10n_it_edi` module and switch to an IT Company. - Create and confirm an invoice for a non-Italian customer. - Send the invoice, making sure that only `by Email` is enabled. - Attempt to send the invoice again. **Issue:** - In `18.0`, the XML file is not generated when re-sending an invoice that was previously sent only by email. - Starting from `19.0`, attempting to `Send to Tax Agency` raises an error: `UnboundLocalError: cannot access local variable 'attachment_name' where it is not associated with a value` **Root cause:** At [1], `_get_alerts` method does not check whether the invoice was previously sent only by email. As a result, the warning banner is not displayed, and allows the user to `Send to Tax Agency`. **Fix:** Restore the expected behavior by preventing `Send to Tax Agency` when the invoice was previously sent only by email. Instead, display the appropriate warning message instructing the user to delete the PDF attachment before sending to the Tax Agency, matching the behavior in `17.0` (confirmed with PO). [1]: https://github.com/odoo/odoo/blob/c0d8d36481e106f0209521bbb127cb3b1ad1059a/addons/l10n_it_edi/models/account_move_send.py#L27-L33 opw-6293519 Forward-Port-Of: odoo/odoo#275498 Forward-Port-Of: odoo/odoo#269547
This update resolves an issue where sales orders could incorrectly show analytic distributions exceeding 100%, leading to confusing accounting reports. The change consolidates analytic distributions from multiple models into a single line, maintaining functionality while ensuring accurate reporting. This improves clarity and prevents potential over-allocation of costs.
Original PR description
Steps: 1. Create an analytic model filtered by partner. 2. Create an analytic model filtered by product. 3. Create a project with an analytic distribution. (Make sure the distributions use different plans) 4. Create an SO for a product within the project that both the models apply to. 5. Confirm the SO. 6. Notice the analytic distribution for the project account is at 200%. When an SOL is created, the analytic distribution from each model is added as a separte line The analytic account for the project is added to each analytic distribution line. This can easily cause the account to have >100% distribution for a given SOL. This is unintuitive and confusing behaviour. This PR changes the behaviour to only create one line for all the distributions from analytic models. This should prevent this behaviour while keeping the functionality of applying the project distribution to each line. opw-6250908 / opw-6304033 Forward-Port-Of: odoo/odoo#270151
This update resolves an issue where attachments added to email templates weren't correctly linked to scheduled messages. Previously, users would encounter access errors when viewing scheduled messages with different user accounts. This change ensures all attachments are properly associated with the scheduled message, improving data consistency and preventing these errors.
Original PR description
**Problem:** When scheduling a message using an email template with custom attachments, those attachments will not have their `res_model` and `res_id` updated to relate to the scheduled message…
**Problem:** When scheduling a message using an email template with custom attachments, those attachments will not have their `res_model` and `res_id` updated to relate to the scheduled message record. This can lead to access errors. **Cause:** When composing a message using an email template with attachments, those attachments are created with their `res_model` and `res_id` values corresponding to the mail composer record. However, when scheduling a message, only attachments with no `res_id` value (or a value of 0) are updated to correspond to the scheduled message record. https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mail/wizard/mail_compose_message.py#L1198-L1201 https://github.com/odoo/odoo/blob/30ca89b9e0d3c43d019167ec2de816c263f4bb92/addons/mail/models/mail_scheduled_message.py#L86 **Purpose:** Modify the `mail.scheduled.message` override of `create` to not require an attachment have no `res_id` value to be properly updated. **Steps to Reproduce in Runbot:** 1. Add an attachment to an email template. 2. Open a mail composer using that email template, then schedule the message for later. 3. Attempt to view the scheduled message with a different user. More specific example flow: 1. Add an attachment to the Sales: Send Quotation email template. 2. Create a Quotation and send it with the Send by Email button, selecting Send Later instead of Send. 3. Attempt to view the Quotation with a different user. opw-6293587 Forward-Port-Of: odoo/odoo#272261
This update fixes an issue where lost leads were not included in reporting totals when grouping leads. The change ensures that all leads, including inactive ones, are properly considered during filtering and grouping, leading to more accurate reporting. This improves the reliability of lead analysis.
Original PR description
Problem: When filtering lost leads and grouping them, the lost leads are not counted in the groups' totals. Steps to Reproduce: 1. Go to CRM 2. Go to Reporting > Leads 3. Select List View 4. Before…
Problem: When filtering lost leads and grouping them, the lost leads are not counted in the groups' totals. Steps to Reproduce: 1. Go to CRM 2. Go to Reporting > Leads 3. Select List View 4. Before applying any grouping, check the total number of leads and make sure there are some closed leads among the leads and that the applied filter includes the inactive/lost leads 5. Apply any grouping 6. Check how the sum of the groups totals doesn't equal the leads total Cause: When reading a group, the domain from the applied filter gets optimized, meaning that the applied rules get simplified logically. https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/web/models/models.py#L421 When looking for all leads, we filter by both active and inactive leads, but the optimize method removes both of them since active=TRUE OR active=FALSE = TRUE always. When removed, no filtering on the active field is in the domain now, which leads to the search method returning only active leads (default behaviour of search method when the active field is not set in the domain). opw-6302388 Forward-Port-Of: odoo/odoo#272390
This update corrects a visual issue in the account module where the dropdown background for account types remained light when dark mode was enabled. The change ensures a consistent dark mode experience by applying the correct background color ($dropdown-bg) to the dropdown element. This improves the overall user interface for users in dark mode.
Original PR description
Steps to reproduce: - Install `account` module - Enable dark mode - Open `view_account_form` to create a record - On the Accounting page, open type dropdown - The dropdown background remains in light mode This commit applies $dropdown-bg on `o_field_account_type_selection` as in odoo/odoo@0cd148eb389078c896aaa719af5733d05377fd1c Forward-Port-Of: odoo/odoo#274626 Forward-Port-Of: odoo/odoo#271352
Miscellaneous changes
### Description: Processing batch payments for multiple invoices triggers the `_increase_rank` method across numerous partners. Previously, this could lead to Out-Of-Memory (OOM) errors in databases with extensive partner hierarchies (parent/child relationships), primarily due to cascaded writes triggered by `_commercial_sync_to_descendants`. This commit optimizes the rank increment process, significantly reducing both memory consumption and execution time. ### Benchmark: | Partner C
Original PR description
### Description: Processing batch payments for multiple invoices triggers the `_increase_rank` method across numerous partners. Previously, this could lead to Out-Of-Memory (OOM) errors in databases with extensive partner hierarchies (parent/child relationships), primarily due to cascaded writes triggered by `_commercial_sync_to_descendants`. This commit optimizes the rank increment process, significantly reducing both memory consumption and execution time. ### Benchmark: | Partner Count | Time Before | Time After | Memory After | |---------------|-------------|------------|--------------| | 191,946 | 2 min | 47s | 111 Mb | | 393,509 | OOM | 1 min 45 | 216 Mb | ### Reference: opw-5152687 Forward-Port-Of: odoo/odoo#259334