Daily updates from Odoo
Wednesday, June 10, 2026
275 changes
13 changes
Resolved issues and error corrections
This update corrects a bug that caused the growth comparison percentage in financial reports to fluctuate when users switched the period order. The original code incorrectly assumed the first period was always the most recent, leading to inaccurate calculations. This change ensures consistent and reliable growth percentage displays regardless of the selected period order.
Original PR description
The feature had originally been implemnted at a time where the period_order couldn't be modified, and always corresponded to what we call 'descending' now. Because of that, we assumed the column at index 0 was always the most recent period ; which caused the growth comparison percentage to change when switching period order. Forward-Port-Of: odoo/enterprise#119782 Forward-Port-Of: odoo/enterprise#118835
This update resolves a previous issue that prevented exporting records with properties from the kanban and list views, specifically causing errors when inserting into spreadsheets. Now, users can reliably export records containing properties, and individual properties displayed in the views are automatically included in the export process.
Original PR description
**Before this commit:** - Exporting records with properties from the kanban view caused a `Client Error`. - Inserting records with properties from the kanban view into a spreadsheet caused a `Client Error`. - Individual properties were not exported by default in list views (even when optionally displayed) or in kanban views. **After this commit:** - Records containing properties can be exported from the kanban view. - Records with properties can be inserted into a spreadsheet without errors. - Individual properties that are optionally displayed are listed by default in `Fields to Export`. enterprise: https://github.com/odoo/enterprise/pull/118913 task-6123524 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268696 Forward-Port-Of: odoo/odoo#264267
This update ensures that sub-properties within records are now correctly exported when using the 'Insert in Spreadsheet' feature. Previously, this functionality was limited, but this fix aligns the export behavior across different views (kanban, list, and spreadsheet) to match the capabilities introduced in version 19.2. This enhances data consistency and usability.
Original PR description
* = [documents_spreadsheet] When exporting properties from records in the web kanban and list views, sub-properties created within a record were previously not supported. Support for exporting these sub-properties has now been added. However, in spreadsheet this should only be enabled from saas-19.2 onwards (where it is already available). To keep the behavior aligned with the usual flow on earlier versions, this filters out the sub-properties exported from the record in `spreadsheet_edition`. community: https://github.com/odoo/odoo/pull/264267 task-6123524 Forward-Port-Of: odoo/enterprise#119603 Forward-Port-Of: odoo/enterprise#118913
This update fixes a login issue in Safari's private browsing mode, where users were unable to complete the turnstile challenge. The fix addresses a conflict between Safari's tracking protection settings and Odoo's turnstile implementation, ensuring seamless login functionality.
Original PR description
Scenario: - set up turnstile - with recent safari mac os or ios (reproduced from 26.2) go to /web/login page in a private window - enter login and password and pass the turnstile challenge - click on…
Scenario: - set up turnstile - with recent safari mac os or ios (reproduced from 26.2) go to /web/login page in a private window - enter login and password and pass the turnstile challenge - click on Log in Result: nothing happens and there is an error in the console "An invalid form control with name='' is not focusable." Cause: By default Safari has the Settings > Advanced > "Use advanced tracking and fingerprinting protection" set to "in Private Browsing". If this options is enabled in private browser or in all browsing, you can't login to Odoo with turnstile because safari is preventing the update of the element that is preventing to send the form: <input style="display: none;" class="turnstile_captcha_valid" required> When turnstile challenge succeeds, a value should be set to this input that will unlock the form, the .value property is updated but the browser Shadow Content is not (and if we remove display:none, the input is empty). Fix: I've not been able to reproduce the issue without turnstile using same situation and iframe. We don't know Safari heuristic but the unlocking is working if: - we use setProperty instead of .value - we unset required - we remove the input - we display the turnstile_captcha_valid input before challenge This fix replaces setting .value by setProperty, and add a failsafe of unsetting required. opw-5917286 fixes #247536 Forward-Port-Of: odoo/odoo#253367
This update resolves an issue that prevented attendee imports on events with scheduled emails, causing import failures. By triggering the asynchronous email queue during imports, the system now correctly handles email scheduling, ensuring reliable attendee import processes. This improves the stability and usability of event registration.
Original PR description
Importing attendees on an event that has an `after_sub` mail scheduler (the default on every event) fails with `savepoint "..." does not exist` and the import is aborted.…
Importing attendees on an event that has an `after_sub` mail scheduler (the default on every event) fails with `savepoint "..." does not exist` and the import is aborted. [`_update_mail_schedulers`](https://github.com/odoo/odoo/blob/b2f3270271f6/addons/event/models/event_registration.py#L298) runs the attendee scheduler synchronously on every registration create. The scheduler commits after each mail batch, which is fine from cron but problematic during an import: since [29460b723f49](https://github.com/odoo/odoo/commit/29460b723f49) [`load`](https://github.com/odoo/odoo/blob/b2f3270271f6/odoo/orm/models.py#L884) uses a single savepoint for the whole run, and any commit underneath releases it, so the next `ROLLBACK TO` / `RELEASE SAVEPOINT` raises `InvalidSavepointSpecification`. When `import_file` is in context, trigger the cron like the async path already does so the mails are queued instead of running inline. Steps to reproduce: 0. Have Contacts and Events installed 1. Events > Events, create a published event 2. Open the event, Attendees tab > Favorites > Import records 3. Upload a file with new attendees (Name, Email, no external id) 4. Click Import => "savepoint ... does not exist", import fails Ticket [link](https://www.odoo.com/odoo/project.task/6124741) opw-6124741 Forward-Port-Of: odoo/odoo#267586 Forward-Port-Of: odoo/odoo#260648
This update significantly speeds up the calculation of future leave balances by fixing a recursive process that was causing performance bottlenecks. The change eliminates a redundant calculation step, resulting in a 98% reduction in processing time for complex employee leave scenarios. This improves the overall responsiveness of the HR module.
Original PR description
## The Problem When computing a future leave balance, `_get_future_leaves_on` triggers `_process_accrual_plans`, which iterates period by period and calls `_get_leaves_taken` at each step.…
## The Problem When computing a future leave balance, `_get_future_leaves_on` triggers `_process_accrual_plans`, which iterates period by period and calls `_get_leaves_taken` at each step. `_get_leaves_taken` re-enters `_get_consumed_leaves` with `ignore_future=True`, but other accrual allocations on the same employee were not guarded by `precomputed_allocations`, causing `_get_future_leaves_on` to fire again for each of them, launching another full accrual run recursively. With N periods and K allocations, total work grew as $O(N^K)$. ## The Solution Adding `not ignore_future` to the guard prevents future projection in any nested context where it is both semantically incorrect and the source of the blowup. --- ## Benchmarks *Tested on a customer database with an employee having 2 accrual allocations and pending future leave requests 6 months out:* | | Queries | Request Time | Improvement | | :--- | :--- | :--- | :--- | | **Before** | 220K | 145.0s | — | | **After** | 2.7K | 2.8s | **-98%** | **Note:** More optimizations could be done to reduce the queries to a constant. However given the current design, it would be a bit big change and the current performance is already acceptable. **OPW-6115804** Forward-Port-Of: odoo/odoo#261172
This update resolves a technical issue that was preventing French VAT reports from generating correctly. Specifically, a formatting error in the XML data caused a failure. The fix ensures accurate report generation by correcting the handling of street address fields.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update significantly speeds up the Inventory Valuation report by filtering products with stock, reducing the amount of data processed. Previously, the report strained system resources, but now it runs 41 times faster on today's data and 1.4x faster for historical reports. This improves report generation times and overall system responsiveness.
Original PR description
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only…
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only products that have stock (under the same valuation context that total_value uses) or that are lot-valuated, and feeds that smaller set into stock_value and stock_accounting_value. For historical (at_date) reports the search runs with to_date in context so qty_available is scoped to that date. _get_accounts_by_product() also switches to search_fetch so only categ_id is loaded upfront. Benchmarks were measured on a customer database restore with ~360k storable products. After filtering, ~2.5k products feed into the valuation today and ~2.2k for a historical date. Benchmark opening Inventory Valuation report (Accounting) | Date | Before | After | Speed up | |------------|--------|--------|----------| | Today | ~88s | ~2s | 41x | | Historical | ~245s | ~173s | 1.4x | The historical improvement is more modest because stock_value still has to compute total_value at the historical date for the remaining products, which traces SVL/stock.move history; the filter eliminates the dominant per-product overhead today but only the tail in the historical case. 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#265931 Forward-Port-Of: odoo/odoo#254010
This update corrects a bug in the sale details report that was failing to include discounts applied through loyalty programs. Previously, the report showed incorrect discount numbers and totals when a loyalty discount was active. This change ensures that all discounts, including those from loyalty programs, are accurately reflected in the report.
Original PR description
When generating the sale details report, the number of discounts would not include the discount given by a loyalty program. The same problem applies for the total discount amount. Steps to reproduce: ------------------- * Create a loyalty program that gives a 10% discount automatically. * Open the PoS and make an order that activate the loyalty program. * Close the session and open the sale details report for this session. > Observation: The discount number and total is 0 opw-6185554 Forward-Port-Of: odoo/odoo#268927 Forward-Port-Of: odoo/odoo#267753
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The change adds a validation to prevent this, ensuring that recurring products are only added when a valid subscription is present, improving data integrity and preventing unexpected errors.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#119955 Forward-Port-Of: odoo/enterprise#107691
This update resolves a performance issue within the tests for the 'Discuss' feature in Odoo. The fix optimizes a database query, resulting in faster test execution times. This improves the overall stability and reliability of the Odoo platform.
Original PR description
runbot-243772 https://github.com/odoo/enterprise/pull/119886 Forward-Port-Of: odoo/odoo#269111
This update addresses a performance issue within the Discuss module, specifically related to how it counts conversations. The change optimizes the query, resulting in faster response times and a smoother user experience. This improvement ensures the Discuss feature remains efficient for all users.
Original PR description
runbot-243772 https://github.com/odoo/odoo/pull/269111 Forward-Port-Of: odoo/enterprise#119886
This update fixes a translation error in Odoo's Argentine localization (l10n_ar) module, ensuring fiscal position names accurately reflect their purpose. Previously, a confusing translation led to duplicate entries, which this change resolves, streamlining the system and improving data clarity.
Original PR description
### Description of the issue/feature this PR addresses: Fix fiscal position spanish translation to match with its real purpose. ### Current behavior before PR: * We have a fiscal position name that does not match with its purpose: Represent the local operations inside argentina (country: Argentina) but the name is " Purchases / Sales abroad" * Two fiscal positions have the same translation value and this is confusing ### Desired behavior after PR is merged: * we do not have duplicated fiscal position anymore * Domestic fiscal position is taged with the correct name --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264257 Forward-Port-Of: odoo/odoo#248462
11 changes
Resolved issues and error corrections
This update addresses a traceback issue that appeared when viewing project calendars. The fix safely handles cases where the 'write_date' field is missing, preventing errors and ensuring the calendar view functions correctly. This resolves a minor instability in the Project app.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install Studio and Project app with demo 2. Go to Project App > studio > views > enable calendar view > close studio 3. Click on any…
Steps to reproduce:
---------------------------------------
1. Install Studio and Project app with demo
2. Go to Project App > studio > views > enable calendar view > close studio
3. Click on any project
Observation:
---------------------------------------
A traceback appears:
```
Caused by: TypeError: Cannot read properties of undefined (reading 'toMillis')
at get uniqueId (http://localhost:8192/web/assets/cbd2032/web.assets_web.min.js:21370:74)
at Many2OneAvatarEmployeeField.template (eval at compile (http://localhost:8192/web/assets/cbd2032/web.assets_web.min.js:1387:421), <anonymous>:25:122)
```
Issue:
---------------------------------------
The traceback is yielded from the `get uniqueId` getter from the `Many2OneAvatarUserField` component:
https://github.com/odoo/odoo/blob/be8b1bbad757fda27df579ce36cbc97324f58f62/addons/mail/static/src/views/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js#L48-L50
where `write_date` is undefined. This getter was added by, https://github.com/odoo/odoo/commit/3732ca85b03bea9eabfb05cc306ce0bf5bac88d4#diff-94c14c7d2a5fe89c7558f5dffbd6cd126bcba0b140e821ef317f25ac15eb9352 which handled the case of undefined `write_date` for the related Kanban component
https://github.com/odoo/odoo/blob/c3172d65db44c41f5619aef20532c3846494ea0e/addons/hr/static/src/views/fields/many2one_avatar_employee_field/kanban_many2one_avatar_employee_field.js#L49-L52
For the Kanban record for User Avatar, a similar solution is applied in this problematic getter. https://github.com/odoo/odoo/pull/251000/changes/80b5e529304ad9a0bdaf55a49e64ac8097a0380a
Solution:
---------------------------------------
Handle missing `write_date` safely using optional chaining to avoid undefined errors
Similar fix applied for the employee avatar in https://github.com/odoo/odoo/pull/260069/changes/6658b41310106bb4e425ae537a1af6a8ed71f864
Note:
---------------------------------------
For `saas-19.3` It is solved in commit https://github.com/odoo/odoo/commit/8847084c14ae4e0595eed7e006c58e161ce450ea
opw-6210249This update resolves an issue where a specific configuration in the French VAT reporting module incorrectly generated an error. When the street address was short and 'street 2' was not used, the system produced invalid XML data. This fix ensures accurate report generation and prevents potential disruptions to the VAT reporting process.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed emails linked to marketing automation campaigns, reducing the risk of unintended spam and ensuring targeted email delivery. A user interface change hides the 'Retry' button to avoid this.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119597 Forward-Port-Of: odoo/enterprise#118759
This update resolves a sporadic test failure related to highlighting the timesheet timer field. The change replaces a temporary workaround with a more reliable method using React's useEffect hook, ensuring consistent test results and improved stability.
Original PR description
This PR replaces the macrotask hack to hightlight the content of the timer field on focus with a more idiomatic useEffect. This ensures the corresponding test won't fail randomly if the macrotask queue happens to not be cleared before we check the highlight.
This update corrects a technical error within the Odoo Enterprise planning module. The issue stemmed from how default values were retrieved, which could result in an error when multiple planning slots were accessed simultaneously. This fix ensures the system functions reliably and prevents potential disruptions to planning processes.
Original PR description
`self` could be non-singletion recordset ``` (Pdb) p self.default_get(['repeat_interval']) *** ValueError: Expected singleton: planning.slot(227, 174) ``` See: 689a15b46c85774f3ab9ee4b9173a549c2ce1abf
This update addresses a recurring problem where payments at self-order kiosks were getting stuck when using the IoT Worldline terminal. The fix allows the system to correctly handle terminal disconnections and provides more specific error messages based on the terminal's feedback, improving the overall payment experience. This prevents frustrating delays for customers.
Original PR description
This PR fixes some payments in pos kiosk being stuck with iot worldline terminal. It allows to succesfully interpret when the terminal is disconnected and adapts the error messages to the information received fromthe terminal instead of the current generic "An error has occurred" enterprise: https://github.com/odoo/enterprise/pull/107709 task-5946033 Forward-Port-Of: odoo/odoo#249582 Forward-Port-Of: odoo/odoo#249101
This update significantly speeds up the Inventory Valuation report by reducing the number of products processed. Previously, the report strained system resources, but now it focuses only on products with stock, dramatically improving performance – particularly for large catalogs. This change ensures the report runs efficiently and reliably.
Original PR description
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only…
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only products that have stock (under the same valuation context that total_value uses) or that are lot-valuated, and feeds that smaller set into stock_value and stock_accounting_value. For historical (at_date) reports the search runs with to_date in context so qty_available is scoped to that date. _get_accounts_by_product() also switches to search_fetch so only categ_id is loaded upfront. Benchmarks were measured on a customer database restore with ~360k storable products. After filtering, ~2.5k products feed into the valuation today and ~2.2k for a historical date. Benchmark opening Inventory Valuation report (Accounting) | Date | Before | After | Speed up | |------------|--------|--------|----------| | Today | ~88s | ~2s | 41x | | Historical | ~245s | ~173s | 1.4x | The historical improvement is more modest because stock_value still has to compute total_value at the historical date for the remaining products, which traces SVL/stock.move history; the filter eliminates the dominant per-product overhead today but only the tail in the historical case. 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#265931 Forward-Port-Of: odoo/odoo#254010
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The change prevents this by validating the product setup, ensuring a subscription plan is present before allowing the recurring product to be added, improving order stability.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#119955 Forward-Port-Of: odoo/enterprise#107691
This update corrects a bug where products without lot/serial tracking incorrectly displayed expiration warnings. The change ensures that products tracked by quantity don't trigger the expiration flow, aligning with intended usage. This prevents unnecessary alerts and streamlines product management.
Original PR description
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup…
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup since from saas-18.4 there is a line where if `ml.removal_date <= datetime.datetime.now()` the picking is expired. So, if the product previously met these conditions, it will still be able to enter this flow. And since this product doesn't use a lot_id it displays “You are going to deliver the product False, False which is expired or should at least be removed from stock” What should happen: When a product is not tracked, use_expiration_date should be False as expiration dates are intended to be managed through lots or serial numbers. Steps to reproduce 1. Enable Product Expiry. 2. Create a storable product with: - Tracking: By Lots - Use Expiration Date: enabled - Set a value greater than 0 for removal_time 3. Change the product tracking to By Quantity. 4. Create and validate a receipt for the product. Related Tickets: opw-6255673 Forward-Port-Of: odoo/odoo#268135
This update corrects a technical issue with how Odoo validates cardholder addresses for Stripe payments. The system was incorrectly using an outdated ISO 3166-2 standard for state codes, causing failures for US addresses. This fix ensures accurate address validation and avoids potential payment processing problems.
Original PR description
Stripe says that address.state is "State, county, province, or region (ISO 3166-2)". There didn't seems to be any issues since it seems that it's not checked for the EU. However, this is still wrong and could raise an issue if Stripe decide to start checking them. Also, with the US coming soon, it's being checked and failed. Forward-Port-Of: odoo/enterprise#114480
This update corrects a bug in how leads are assigned to sales teams, ensuring a more equitable distribution of leads. Previously, team members created earlier received a disproportionate number of leads, particularly when quotas were equal. The fix introduces random tie-breaking to prevent this bias and ensure fair lead assignment.
Original PR description
_assign_and_convert_leads() is biased towards team members created earlier because they're ordered by create_date, id. When members have equal quota, the round-robin order falls back to the order of the team members. If the amount of leads distributed across the team is not a multiple of the team size, then the oldest members will get more leads assigned. This advantage repeats each time the cron runs and can add up to a big difference, the provided test case ends up assigning all 30 leads to the more senior member without the fix. Note that the lead_day_count field used in _get_assignment_quota() doesn't solve the problem. It helps to balance leads assigned in the same 24 hour window, but because the same senior person always goes first inside one of those windows, they will always get more leads assigned to them. To fix it we break ties in the quota randomly. task-6119168 Forward-Port-Of: odoo/odoo#268716 Forward-Port-Of: odoo/odoo#259775
9 changes
Resolved issues and error corrections
This update significantly speeds up the calculation of future leave balances by fixing a recursive process that was causing performance bottlenecks. The change eliminates unnecessary calculations, resulting in a 98% reduction in processing time. This improves the responsiveness of the HR module for users.
Original PR description
## The Problem When computing a future leave balance, `_get_future_leaves_on` triggers `_process_accrual_plans`, which iterates period by period and calls `_get_leaves_taken` at each step.…
## The Problem When computing a future leave balance, `_get_future_leaves_on` triggers `_process_accrual_plans`, which iterates period by period and calls `_get_leaves_taken` at each step. `_get_leaves_taken` re-enters `_get_consumed_leaves` with `ignore_future=True`, but other accrual allocations on the same employee were not guarded by `precomputed_allocations`, causing `_get_future_leaves_on` to fire again for each of them, launching another full accrual run recursively. With N periods and K allocations, total work grew as $O(N^K)$. ## The Solution Adding `not ignore_future` to the guard prevents future projection in any nested context where it is both semantically incorrect and the source of the blowup. --- ## Benchmarks *Tested on a customer database with an employee having 2 accrual allocations and pending future leave requests 6 months out:* | | Queries | Request Time | Improvement | | :--- | :--- | :--- | :--- | | **Before** | 220K | 145.0s | — | | **After** | 2.7K | 2.8s | **-98%** | **Note:** More optimizations could be done to reduce the queries to a constant. However given the current design, it would be a bit big change and the current performance is already acceptable. **OPW-6115804** Forward-Port-Of: odoo/odoo#261172
This update fixes an issue where product descriptions weren't correctly appearing on manufacturing orders (MOs) created from Point of Sale (POS) orders. The change ensures that all product variants, especially those with custom attributes, have accurate descriptions displayed on MOs, aligning with how descriptions are handled in the standard sale module. This improves clarity and consistency for users managing orders.
Original PR description
**Steps to reproduce:** - Install pos_mrp - Make a BoM for a product - The product must have a custom attribute, of type always - Go to the PoS - Make a sale, with a customer, enable Ship Later - Go…
**Steps to reproduce:** - Install pos_mrp - Make a BoM for a product - The product must have a custom attribute, of type always - Go to the PoS - Make a sale, with a customer, enable Ship Later - Go to the created MO - The Custom Description field is not showing **Why the fix:** This fix was previously done by e53dae2 but it did not account for the other variants and only did the fix for the never attributes. This is because it seemed to work with other kinds of attributes until 19.0 We now also compute the move description if we have a custom attribute. We need the never variants to have a description as well, as it is done in the sale module. This commit basically aligns the behavior to the on done in the sale module. A test had to be changed, as we now write the description in a different way, to make it the same regardless of where the picking and moves were created from. We now won't see a difference on the MO between one created from the POS and one created through the sale module. opw-6169257 Forward-Port-Of: odoo/odoo#263350
This update resolves an issue where a specific configuration in the French VAT reporting module was generating an error. When the street address was short and 'street 2' was marked as false, an incorrect value ('False') was being written to the report's XML, causing a processing failure. This fix ensures accurate report generation and avoids potential disruptions.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The change adds a validation step to prevent this, ensuring that recurring products are only added when a valid subscription is present, improving data integrity and preventing unexpected errors.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#119955 Forward-Port-Of: odoo/enterprise#107691
This update resolves a technical issue where removing the quantity input field on rental product pages caused a website error. The change was due to a recent architectural update that moved data evaluation logic directly into the website component, leading to a crash when the input field was removed. This fix ensures the website remains stable and functional.
Original PR description
Steps to reproduce: 1. Install website_sale_renting_planning 2. In rental module, create a product that is of type service and can be sold 3. Go to the website and remove the quantity selector input field from the page and save. Issue: `TypeError: Cannot read properties of null (reading 'dataset')` Why this happens: Following architectural changes in v19.1, the rental data evaluation logic was moved directly into the DaterangePicker component lifecycle. Commit 4e5f71d introduces a new method to where, during initialization (`willStart`), the component triggers `setAddQtyInputMax()` to update the dataset attributes of the quantity selector input box. If the quantity selector has been removed via the website customizer `querySelector` returns `null`, causing the assignment to crash. In v19.0, this logic lived in the `WebsiteSale` interaction, executing only during post-render UI event listener triggers which kept it safe. opw-6268945
This update fixes an issue where planned dates were lost when converting projects to project templates. The change ensures that the original planned dates are correctly copied to the new template, improving project tracking accuracy. This prevents data loss and ensures consistent project planning.
Original PR description
****Steps** to reproduce:** - Open a project with a planned date set. - Create Template of that project. - Observe the created project template. **Issue:** The planned dates of the project are lost when converting the project into a template. **Cause:** When we create a project template from a project, the project gets archived. Because a new project template record is created, and the start and expiration fields have copy=False, those dates are not being copied. **Fix:** Explicitly pass the planned date when copying the project, so the project template keeps the original planned date. task-5872500 Forward-Port-Of: odoo/odoo#269159 Forward-Port-Of: odoo/odoo#249411
This update fixes an issue where planned dates were lost when converting projects to templates. The change ensures that project templates retain the original planned dates, improving accuracy and usability for project management. This resolves a previous data inconsistency.
Original PR description
Steps to reproduce: -------- - Open a project with a planned date set. - Create Template of that project. - Observe the created project template. Issue: ---------- The planned dates of the project are lost when converting the project into a template. Cause: ----- When we create a project template from a project, the project gets archived.Because a new project template record is created, and the start and expiration fields have copy=False, those dates are not being copied. Fix: ------- Explicitly pass the planned date when copying the project, so the project template keeps the original planned date. task-5872500 Forward-Port-Of: odoo/enterprise#119921 Forward-Port-Of: odoo/enterprise#115035
This update prevents unnecessary placeholder images from being sent during menu synchronization. By only transmitting actual image URLs when images are defined, we've optimized the data being transferred, leading to faster menu updates and a smoother user experience. This change improves the efficiency of the Odoo Enterprise system.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119883 Forward-Port-Of: odoo/enterprise#119482
This change resolves an issue where extremely long invoice reference strings in the general ledger report were causing wkhtmltopdf to generate bloated PDF files. By limiting the length of the reference string, we prevent the PDF from becoming excessively large and ensure reports generate reliably. This improves report performance and avoids system errors related to file descriptor limits.
Original PR description
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single…
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single invoice, the ref can become extremely long, e.g.: INV/2026/00001 (S12123, S12152, S12159, S12140, S12165, S12161, S12162, S12110, S12099, S12124, S12145, S12128, S12114, S12131, S12097, S12185, S12154, S12133, S12190, S12118, S12116, S12102, S12155, S12153, S12158, S12150, S12100, S12142, S12121, S12122, S12111, S12187, S12172, S12177, S12095, S12117, S12144, S12137, S12092, S12138, S12186, S12182, S12112, S12148, S12183, S12101, S12178, S12119, S12169, S12115, S12146, S12093, S12126, S12160, S12163, S12129, S12098, S12151, S12096, S12174, S12120, S12130, S12147, S12180, S12191, S12164, S12141, S12105, S12136, S12139, S12109, S12106, S12104, S12103, S12175, S12179, S12188, S12113, S12173, S12167, S12171, S12134, S12094, S12184, S12166, S12170, S12125, S12135, S12143, S12176, S12189, S12156, S12181, S12107, S12157, S12132, S12149, S12127, S12108, S12168...) Because the length of the account.report.line is unchecked in account_general_ledger.py label builder, the pdf can clog to one or two account.report.lines per page, skyrocketing the pdf page length. As wkhtmltopdf processes the report from html to pdf it makes a system call openat() to the /tmp/report.footer.tmp.x.html file for EACH page of the pdf. You can see the TODO comment in the spoolTo function in wkhtmltopdf (both in Odoo and the original repo) saying that the header and footer need to be freed, on each page processing, not just null pointed. https://github.com/odoo/wkhtmltopdf/blob/2c884bd1545b8a639847de22f24754ee5a6fc44c/src/lib/pdfconverter.cc#L794 I verified that that the number of openat calls to the /tmp/report.footer.tmp.x.html file equals the exact number of pages in the pdf to be generated if the report HAD generated successfully by setting the footer input into _run_wkhtmltopdf to None, generating the report without footers, then separately running an strace on wkhtmltopdf when the report fails to generate. See related ticket linked at bottom. The linux machine used on sh instances has a ulimit -n of 1024 file descriptors. Because the footer file descriptors accumulate, once a pdf has about 1010+ pages (~a dozen fd's are allocated for other purposes), over 1024 file descriptors are opened and the system fails with: Wkhtmltopdf failed (error code: -6). Message: QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe Since wkhtmltopdf is archived and Odoo has a replacement in development, I suggest that we limit the display_name of the account.report.line to 200 to keep the bloat minimized, preventing one account.report.line's name from taking up an entire page of the general ledger pdf. This allows many more batched invoices to be shown in the report and a much greater time range of data to be printed without hitting the fd limit. I suggest changing it at the general ledger report level rather than in the account.move.line _compute_display_name function, as we probably still want to see the full display_names at the invoice level. On runbot, the machine has different memory constraints than on sh / local, so it hits the following error before the one above: Wkhtmltopdf failed (error code: -11). Memory limit too low or maximum file number of subprocess reached. Message : Steps to Reproduce on 19.0 newdb: 1. newdb -n test_gl -v 19.0 2. ensure ulimit is set to 1024 in shell that runs odoo instance by running ulimit -n 1024 to mimic ulimit of sh environment 3. run db with python3 odoo-bin, ensuring high enough memory constraints to simulate multi worker sh instance, i.e. --limit-memory-soft=12884901888 --limit-memory-hard=1288490188 4. install sales, accounting, stock 5. install demo data 6. create invoices with 100+ associated sales orders 7. generate the pdf 8. Increase the amount of invoices till the general ledger page count hits ~1010+, where you will hit the error. Notes: opw-ticket-6201508 closes #118067 Forward-Port-Of: odoo/enterprise#118067
7 changes
Resolved issues and error corrections
This update resolves a potential error in the Hong Kong payroll calculations. The fix ensures the system doesn't divide by zero when a company's resource calendar is missing or if an employee has zero hours per week. This prevents inaccurate payroll processing and ensures correct payments.
Original PR description
. Add a check for a null resource calendar and zero hours per week. task-6229271 Forward-Port-Of: odoo/enterprise#117685
This update prevents users from directly creating employee, cost, or mandatory benefits records through the Benefits form. This change ensures data integrity by requiring these records to be created through the standard HR contract workflow, improving data accuracy and reducing potential errors.
Original PR description
This commit prevents creating new employee, cost or mandatory benefits records directly from the Benefits form by setting these fields' `'no_create'` to `True`. task-5156844 Forward-Port-Of: odoo/enterprise#96770
This update corrects a display issue in the journal report when multiple countries are used for tax calculations. Previously, the report incorrectly rendered column widths and, critically, failed to show country selections with more than two options. This ensures accurate tax reporting across multiple jurisdictions.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore. Forward-Port-Of: odoo/enterprise#119348
This update resolves an issue where users with limited accounting rights incorrectly marked invoices as fully paid during bank reconciliation, leading to inaccurate financial reporting. The fix ensures proper reconciliation matching by safely bypassing a user permission check within the automated process, maintaining data auditability.
Original PR description
### Issue When you have an invoice partially paid via a method using an Outstanding Account, the payment can be kept open, leaving the invoice considered as partially paid If a user with only…
### Issue When you have an invoice partially paid via a method using an Outstanding Account, the payment can be kept open, leaving the invoice considered as partially paid If a user with only "Invoicing & Banks" rights tries to reconcile a Bank Statement with the same partner, amount, and the invoice name as the memo, the automatic reconciliation fails to properly match the payment Instead, the invoice is incorrectly considered as Fully Paid with an unwanted extra Account Receivable line added ### Cause When a new Bank Statement is created, `_try_auto_reconcile_statement_lines()` is called and matches the outstanding credit, which invokes `set_line_bank_statement_line()` This function creates a balancing line and triggers `move._compute_checked()` to update dependencies However, `move.checked` requires `_is_user_able_to_review()` to be True A user with "Invoicing & Banks" rights lacks the `account.group_account_user` group, meaning the move is not marked as checked, preventing dependencies from computing correctly Consequently, the statement line's `amount_residual` is not cleared and the line is not removed from `remaining_st_line_ids` Later in the process, `_try_auto_reconcile_statement_lines()` is called again with `with_user(SUPERUSER_ID)` Because the payment matching was never finalized in the previous step, the engine fallback matches against the full invoice, adding an incorrect Account Receivable line to close it ### Steps to reproduce - Install `accountant` - Go to Accounting / Configuration / Accounting / Journals - Open the Bank, under Incoming Payments tab, set the Manual Payment method's Outstanding Receipts account to 101403 Outstanding Receipts - Update the Demo user's accounting rights to Invoicing & Banks - Log in with the Demo user - Create and confirm an invoice for Acme Corporation (Amount: $1100) - Register a payment on the invoice (Amount: $500, Keep open) - Copy the invoice name - Open the Bank Reconciliation widget from the Accounting Dashboard - Create and add a new Bank Statement Line (Label: Invoice name, Partner: Acme Corporation, Amount: $500) Before the fix, an unexpected Account Receivable line is created and the invoice is marked as Fully Paid ### Notes Instead of processing the entire block under SUPERUSER_ID, which would hide the creator identity in logs and chatter, the context key `skip_account_review_check=True` is injected during the automated statement line reconciliation This safely bypasses the group check inside `_is_user_able_to_review` for this specific automated flow A fallback using `.with_user(SUPERUSER_ID)` is already implemented twice within the same `_try_auto_reconcile_statement_lines` method for this specific use case, but avoiding it here preserves data auditability opw-6077137
This update resolves an issue where a specific combination of input data (short street address and a 'false' setting for a second street) was causing errors in the generation of French VAT reports. The fix ensures accurate report formatting and prevents potential processing failures, improving the reliability of this important financial reporting process.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
A recent issue preventing users from adding cover images to Knowledge articles has been resolved. The fix corrects a technical error within the Knowledge module related to how cover uploads were handled, ensuring a smoother user experience. This resolves a crash that occurred during the upload process.
Original PR description
Steps to reproduce: 1. Install Knowledge. 2. Create an article. 3. Open the more actions menu. 4. Click "Add Cover". 5. Upload a cover image. Issue: - The upload crashes with the following traceback: `Uncaught Promise > this.props.setAbortUploadsCallback is not a function` Cause: - `KnowledgeCoverSelector` extends the html_editor `ImageSelector`, whose upload flow registers an abort callback through setAbortUploadsCallback. The generic MediaDialog provides this callback, but KnowledgeCoverDialog renders KnowledgeCoverSelector directly and did not pass it. As a result, the inherited upload flow called a missing prop. Solution: - Pass setAbortUploadsCallback from KnowledgeCoverDialog to KnowledgeCoverSelector and abort pending uploads when the cover dialog is discarded. Alternative approach: - Make ImageSelector tolerate callers that do not provide setAbortUploadsCallback by calling it with optional chaining. opw-6176716
This update fixes an issue where placeholder images were unnecessarily included in menu synchronization, leading to slower loading times. Now, only actual product images are sent, resulting in a more efficient and responsive menu display for users. This change improves the overall user experience.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119883 Forward-Port-Of: odoo/enterprise#119482
9 changes
Resolved issues and error corrections
This update resolves a technical issue where the journal report's multi-country tax grids were incorrectly displaying country information when multiple countries were selected. The fix ensures that all countries are accurately represented in the report, improving the accuracy of financial reporting across various regions.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore. Forward-Port-Of: odoo/enterprise#119348
This update clarifies the invoice print process by making the print button secondary to the send action. Previously, invoices were incorrectly labeled as 'proforma,' which is handled separately. This change ensures invoices are consistently displayed and simplifies the invoicing workflow.
Original PR description
Revert 3ef2c09 which incorrectly added a proforma label when printing posted invoices that had not yet been sent, proforma invoices have an entire feature in the sales app, so an invoice in invoicing should just be an invoice in all cases. --- The Print button on posted invoices was visually styled as a primary action. Make it secondary so the Send action keeps the main visual emphasis, while Print remains available with the same behavior. task-6269645 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268552
This update resolves an issue where a specific configuration in the French VAT reporting module incorrectly generated an error. When the street address was short and 'street 2' was not used, the system produced invalid XML. This fix ensures accurate report generation and avoids potential disruptions to the reporting process.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update fixes an issue where Unicode slugs were incorrectly combining characters instead of using separators. Previously, `/` characters were silently removed, resulting in incorrect URL formatting. Now, slugs will correctly use hyphens to separate words, ensuring consistent and accurate URL generation.
Original PR description
After Unicode slug support was introduced in https://github.com/odoo/odoo/commit/926e45aa93ffc3f74fe9bf4ae8f06642976c2ae5, `/`
characters started being silently removed instead of treated as
slug boundaries.
As a result:
"foo/bar" -> "foobar"
while it should instead generate:
"foo/bar" -> "foo-bar"
This restores the previous behavior by treating each non word character
as separators normalized to `-`.
task-6219984This update fixes a problem preventing Odoo logins via turnstile in Safari's private browsing mode. Safari's tracking protection settings were interfering with the form submission process. The fix adjusts how the turnstile challenge is handled to ensure successful logins in this scenario.
Original PR description
Scenario: - set up turnstile - with recent safari mac os or ios (reproduced from 26.2) go to /web/login page in a private window - enter login and password and pass the turnstile challenge - click on…
Scenario: - set up turnstile - with recent safari mac os or ios (reproduced from 26.2) go to /web/login page in a private window - enter login and password and pass the turnstile challenge - click on Log in Result: nothing happens and there is an error in the console "An invalid form control with name='' is not focusable." Cause: By default Safari has the Settings > Advanced > "Use advanced tracking and fingerprinting protection" set to "in Private Browsing". If this options is enabled in private browser or in all browsing, you can't login to Odoo with turnstile because safari is preventing the update of the element that is preventing to send the form: <input style="display: none;" class="turnstile_captcha_valid" required> When turnstile challenge succeeds, a value should be set to this input that will unlock the form, the .value property is updated but the browser Shadow Content is not (and if we remove display:none, the input is empty). Fix: I've not been able to reproduce the issue without turnstile using same situation and iframe. We don't know Safari heuristic but the unlocking is working if: - we use setProperty instead of .value - we unset required - we remove the input - we display the turnstile_captcha_valid input before challenge This fix replaces setting .value by setProperty, and add a failsafe of unsetting required. opw-5917286 fixes #247536 Forward-Port-Of: odoo/odoo#253367
This update ensures that tax details are now included in test orders sent to UrbanPiper. Previously, test orders lacked this crucial information, leading to potential issues with the integration. This change corrects a technical detail to guarantee consistent data transmission and improve the reliability of our testing process.
Original PR description
Commit 1: ======== Before this commit: =================== - Test orders sent to UrbanPiper did not include tax details for order items. After this commit: ================== - Tax details are now included in the order item payload of test orders. Task-6013007 --- Commit 2: ======== Cause: ====== In the `without demo` environment, the discount product does not have any `taxes_id`, causing the test assertion to fail. Fix: ==== Set a tax on the discount product in the test to ensure the same behavior in both `with demo` and `without demo` environments. Error-241138 Forward-Port-Of: odoo/enterprise#109958
This update prevents users from directly creating employee, cost, or mandatory benefits records through the Benefits form. This change ensures data consistency and accuracy by requiring these records to be created through the standard workflow, reducing potential errors and improving data management within the HR contract module.
Original PR description
This commit prevents creating new employee, cost or mandatory benefits records directly from the Benefits form by setting these fields' `'no_create'` to `True`. task-5156844 Forward-Port-Of: odoo/enterprise#96770
This update simplifies invoice sending by ensuring the 'By Peppol' method is only automatically enabled for customers in designated countries (GR, IT, PL, PO, RO). This reduces user confusion and streamlines the invoicing process for businesses operating in these regions.
Original PR description
Current behavior before PR: - If the customer has a valid Peppol endpoint, the 'By Peppol' invoice sending method is selected by default. - For countries like 'GR,' 'IT,' 'PL,' 'PO,' and 'RO,' peppol is not mandatory or not used for sending invoice. It brings noise and it bothers the users. Desired behavior after PR is merged: - The 'By Peppol' invoice sending method is set to true by default only for customers from PEPPOL_DEFAULT_COUNTRIES. Changes Implemented: - Moved the countries 'GR', 'IT, 'PL', 'PO', and 'RO' from PEPPOL_DEFAULT_COUNTRIES to PEPPOL_LIST. - Added condition to set 'By Peppol' invoice sending method to true when customer is from PEPPOL_DEFAULT_COUNTRIES. task-6072935 Forward-Port-Of: odoo/odoo#269106 Forward-Port-Of: odoo/odoo#262402
This update fixes a security vulnerability where users could view financial budgets belonging to other companies. The change adds a security rule to restrict access to budgets based on the company a user is connected to, ensuring data privacy and compliance. This prevents unauthorized access to sensitive financial information.
Original PR description
**Steps to reproduce:** - Install the `account_reports` module. - Create a new company. - Navigate to Accounting > Configuration > Financial Budgets. - Create a new budget record. - Switch to another company. - Open the list view of Financial Budgets. **Observation:** The budget record created in another company is still visible. **Root Cause:** The model `account.report.budget` does not have any record rule restricting access based on company. As a result, users can see financial budgets belonging to other companies even if they are not connected to them. **Fix:** This commit allows users to hide financial budgets from companies they are not connected to by adding a record rule on `account.report.budget` opw-6083892 Forward-Port-Of: odoo/enterprise#114771
3 changes
Resolved issues and error corrections
This update resolves a technical issue that was preventing the generation of French VAT reports. Specifically, a formatting error in the XML data caused an error during processing. The fix ensures accurate report generation by correcting the handling of street address fields.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update prevents users from directly creating employee, cost, or mandatory benefits records through the Benefits form. This change ensures data integrity by requiring these records to be created through the standard HR contract workflow, reducing the risk of incomplete or inaccurate information.
Original PR description
This commit prevents creating new employee, cost or mandatory benefits records directly from the Benefits form by setting these fields' `'no_create'` to `True`. task-5156844 Forward-Port-Of: odoo/enterprise#96770
This update fixes an issue where users could see financial budgets created in other companies within the Odoo Enterprise system. The change adds a security rule to restrict budget access based on company connection, ensuring users only see budgets relevant to their assigned company. This enhances data security and simplifies financial reporting.
Original PR description
**Steps to reproduce:** - Install the `account_reports` module. - Create a new company. - Navigate to Accounting > Configuration > Financial Budgets. - Create a new budget record. - Switch to another company. - Open the list view of Financial Budgets. **Observation:** The budget record created in another company is still visible. **Root Cause:** The model `account.report.budget` does not have any record rule restricting access based on company. As a result, users can see financial budgets belonging to other companies even if they are not connected to them. **Fix:** This commit allows users to hide financial budgets from companies they are not connected to by adding a record rule on `account.report.budget` opw-6083892 Forward-Port-Of: odoo/enterprise#114771
2 changes
Resolved issues and error corrections
This update fixes a technical issue that caused a traceback when generating the annual report within the knowledge app. The fix ensures proper handling of component data, preventing errors during loading and improving the user experience. This resolves a minor performance concern.
Original PR description
Before this commit: when going to the annual report from the knowledge app, select the balance sheet, there's a traceback loading the embedded component. The reason is the props is being reassigned inside the component. Related commit: 8bde58bd2ec1b4925552cebcf5fb3159d88eea00 After this commit: we properly create a value for the translated name in the component and its template. task-6292898
This update streamlines the context keys used when creating accounting entries for work orders. Previously, multiple keys performed similar functions, leading to potential confusion. This change consolidates and clarifies the context, ensuring more reliable and predictable accounting processes.
Original PR description
Replace the `employee_change_id` context key passed when calling `_create_analytic_entry` by adding an optionnal parameter, `previous_employee_id`. Community PR: odoo/odoo#265722 Upgrade PR: odoo/upgrade#10288
6 changes
Resolved issues and error corrections
This update resolves a problem where users couldn't archive employees after installing the 'l10n_be_hr_payroll_dimona_auto' module. The fix adds necessary access rights, ensuring users can correctly archive employees without encountering errors. This improves the stability and usability of the employee archiving process.
Original PR description
In the test `test_user_can_archive_another_employee`, the user is given the group `hr.group_hr_user` to be able to archive an employee. However when the module `l10n_be_hr_payroll_dimona_auto` is installed, some fields need the group `hr_payroll.group_hr_payroll_user` to be read. This leads to an access error. This commit adds sudo access when archiving an employee, Similar to how it is done here: https://github.com/odoo/enterprise/blob/5b3806d78a7998f130d87e56b649e4f4a8cf2bca/l10n_be_hr_payroll/models/hr_employee.py#L398 to avoid access right issues. Runbot error: [error-233177](https://runbot.odoo.com/odoo/error/233177)
This update fixes an issue where purchase transactions were incorrectly identified as intra-state, leading to inaccurate reporting. The change separates sales and purchase transactions during computation, ensuring the correct transaction type is assigned. A migration script has also been added to update existing databases.
Original PR description
Previously, for purchase journals, `l10n_in_state_id` was always computed using the current company `state_id`. However, in `_compute_l10n_in_transaction_type`, the `l10n_in_state_id` was compared with the company `state_id` for both sales and purchases. As a result, all purchase transactions were always computed as intra-state, including inter-state vendor bills. This commit handles sales and purchase transactions separately while computing `l10n_in_transaction_type` to ensure the correct transaction type is assigned. Migration also added to update it in existing dbs.
This update fixes an issue where created packages weren't displayed in the barcode app during the 'Put in Pack' process. Now, users will see the source and destination packages when nesting them, providing clearer visibility into the picking workflow. This improves the user experience and reduces potential errors.
Original PR description
### Steps to reproduce: - Enable `Lots & Serial Numbers` and `Packages` in the settings - Create a product tracked by SN and add SN001 and SN002 to stock - Create and confirm a delivery for 2 units -…
### Steps to reproduce: - Enable `Lots & Serial Numbers` and `Packages` in the settings - Create a product tracked by SN and add SN001 and SN002 to stock - Create and confirm a delivery for 2 units - Open the Barcode app and open the delivery - Scan the product > Scan SN001 - Click `Put in Pack` ### Current behavior: The created package is not displayed anywhere. Clicking Put in Pack again nests the package into another package without any visible indication to the user. ### Cause of the Issue: The GroupedLineComponent cannot display neither the source or destination package: https://github.com/odoo/enterprise/blob/c5bbcaeed513817fdda1f3f42f4c9b2440264174/stock_barcode/static/src/components/grouped_line.xml#L4-L21 However, our case the grouped line contains only a single line and prevents the users from viewing the sublines since the `Show Reserved Lots` is disabled on the operation type and only one lot (with additional demand) was scanned: https://github.com/odoo/enterprise/blob/c5bbcaeed513817fdda1f3f42f4c9b2440264174/stock_barcode/static/src/components/grouped_line.js#L75-L77 https://github.com/odoo/enterprise/blob/c5bbcaeed513817fdda1f3f42f4c9b2440264174/stock_barcode/static/src/components/grouped_line.js#L44-L55 opw-6237834
This update fixes a technical issue in the French VAT reporting module that was causing errors due to incorrect data formatting. Specifically, when the street address was short, a "False" value was incorrectly included in the XML, leading to processing problems. This change ensures accurate VAT report generation.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update resolves an issue where placeholder images were unnecessarily included in the menu synchronization process. By only sending actual image URLs, we've reduced data transfer and improved the speed and efficiency of menu updates, particularly for products with images. This results in a smoother user experience.
Original PR description
This commit prevents placeholder images from being included in the menu sync payload and only sends `img_url` when an actual image is configured on the product or category. Task-6251430 Forward-Port-Of: odoo/enterprise#119883 Forward-Port-Of: odoo/enterprise#119482
This update resolves a technical issue where the journal report's multi-country tax grids were incorrectly displaying country names when multiple countries were selected. The fix ensures that all country options are correctly shown, improving the accuracy of financial reporting across various international operations. This update corrects a display error impacting multi-currency reporting.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore. Forward-Port-Of: odoo/enterprise#119348
8 changes
Resolved issues and error corrections
This update fixes an issue where refunds made from the PoS interface didn't accurately update the quantity invoiced on the associated sale order. The fix ensures that refund lines are correctly considered when calculating the invoiced quantity, resolving a previous inconsistency between PoS and backend refund processes.
Original PR description
When making a refund of a PoS order that was created from a sale order, the sale order qty_invoice was not updated correctly. Steps to reproduce: ------------------- * Create a sale order with any product and confirm it * Open a PoS and settle the order * At this point the qty_invoiced should be 1 on the sale order line * Refund the PoS order from the PoS > Observation: The qty_invoiced is still one. Why the fix: ------------ We now take refund lines into account when computing the qty_invoiced. Note: ------------ There was an inconsistency between a refund made from the PoS and a refund made from the backend. The former is not linking the sale order line to the refund line, while the latter does. This was causing issue when refunding from the backend as it would count the refund twice. To fix this we now remove the link to the sale order line when refunding from the backend. opw-4991405
This update resolves a problem where PDF links within the Odoo viewer were not working correctly. The fix adjusts the layering of elements to ensure clicks are properly directed to the PDF links, improving document navigation. This ensures users can reliably access links within PDF documents.
Original PR description
Version - 18.0 Steps to reproduce: 1. Upload a PDF document containing bookmarks and internal/external links 2. Open the document 3. Click on the links, some work and some do not Issue: `canvas_layer_0` is positioned over the PDF viewer with `z-index: 1`, intercepting clicks intended for PDF link annotations and making internal/external links unresponsive. The `.textLayer` already has `z-index: 2 !important` in iframe.css to prevent the same problem for text selection Fix: Added `z-index: 2 !important` to `.annotationLayer section` in `iframe.css` raising it above `canvas_layer_0`. Taskid = 6237688
This update resolves a requirement from Luxembourg auditors regarding the classification of partners in our SAFT reports. Specifically, it ensures that less than 30% of transactions with payable or receivable accounts have missing supplier or customer IDs, aligning with Luxembourg's FAIA reporting standards. The changes automatically update partner listings and maintain compatibility with older report formats.
Original PR description
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on…
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on \Transaction\Line elements is determined by a partner's `customer_rank` and `supplier_rank`. This is a binary designation, one or the other. The Luxembourg FAIA report requires that less than 30% of \Transaction\Line elements with payable accounts (class 6) can not have \SupplierID. The same applies for \Transaction\Line elements with receivable accounts (class 7) and the \CustomerID element. TSB clarified that any partner on an receivable or payable line should be added to the Customer list or Supplier list respectively https://github.com/odoo/enterprise/pull/100749#issuecomment-3655127511. In addition, I verified that Luxembourg's analysis of four separate FAIA files (from ticket 5427296) aligns with this expectation. <img width="1322" height="690" alt="image" src="https://github.com/user-attachments/assets/1a82f99e-5b32-4dbb-96e1-1b25bab2629b" /> This commit adds partners to the \Supplier and \Customer lists if they have any payable or receivable lines, respectively. It also picks between the \CustomerID and \SupplierID based on a line's `account_type`. This logic is applied to `account_saft` and updates the other, country-specific SAFT reports where appropriate. It also retains the previous `customer_rank` and `supplier_rank` logic as a fallback for older XML reports and for accounts other than `asset_receivable` or `liability_payable`. opw-6118024 Forward-Port-Of: odoo/enterprise#118714
This update resolves an issue where attempting to create a new Global Invoice after cancelling a refund in the Mexican CFDI POS module would fail. The fix ensures that refund CFDI documents are correctly updated during the cancellation process, allowing for seamless invoice creation. This improves the reliability of the POS system for Mexican businesses.
Original PR description
Steps to reproduce 1. With a Mexican POS configured, create a POS order and sign a Global Invoice for it. 2. Open a new session and partially return the order; close the session. 3. On the original…
Steps to reproduce 1. With a Mexican POS configured, create a POS order and sign a Global Invoice for it. 2. Open a new session and partially return the order; close the session. 3. On the original order, cancel the Global Invoice through the CFDI page. 4. Try to create a new Global Invoice for the original order. Issue The wizard raises "Orders <REFUND-NAME> are already sent or not eligible for CFDI." Validating the refund auto-signs an `invoice_sent` CFDI on the refund pos.order because its parent is `global_sent`, see `_l10n_mx_edi_check_autogenerate_cfdi_refund` at https://github.com/odoo/enterprise/blob/5af8048f0b0956a024d7eaeb10600eec74bdf3ee/l10n_mx_edi_pos/models/pos_order.py#L98. Cancelling the GI only flips its own document to `ginvoice_cancel`; the refund's `invoice_sent` doc stays untouched, so the refund's computed `l10n_mx_edi_cfdi_state` stays `'sent'`. The chain check in `_l10n_mx_edi_check_orders_for_global_invoice` at https://github.com/odoo/enterprise/blob/5af8048f0b0956a024d7eaeb10600eec74bdf3ee/l10n_mx_edi_pos/models/pos_order.py#L184 then rejects the refund as already sent and the new GI cannot be created. opw-6181136
This update resolves an issue where users without HR access rights were seeing a placeholder image instead of their avatar in the timesheet kanban view. The fix ensures that all users can see their avatar, improving the user experience and making timesheet management more visually clear.
Original PR description
Steps to reproduce:
- Install the hr_timesheet module
- Create a user without HR access rights
- Create a timesheet
- Log in with the above user
- Open the kanban view
Issue:
Instead of showing the employee's avatar, a placeholder image
is displayed.
Reason:
The user does not have access to the hr.employee model.
Fix:
In this commit, if the user does not have access to hr.employee,
we fetch the image from the hr.employee.public model.
Task: 4461272
X-original-commit: b3018b1ab4bcdfebd8bb83bad38209b96646da3c
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-prThis update fixes an issue where the 'Due' button wasn't appearing for customers when their outstanding balance was present, specifically when the customer was only linked to a journal entry at the line level. The fix ensures all customers with balances are correctly identified, improving the user experience and preventing missed follow-up actions.
Original PR description
Steps to Reproduce: 1. Install Accounting module (without Point of Sale). 2. Create a customer. 3. Create a journal entry with that customer set only at line level. 4. Post the journal entry. 5. Open…
Steps to Reproduce: 1. Install Accounting module (without Point of Sale). 2. Create a customer. 3. Create a journal entry with that customer set only at line level. 4. Post the journal entry. 5. Open the customer form. Issue: The Due smart button is not visible on the partner form even though an outstanding balance exists for the customer. Note: This issue does not reproduce when Point of Sale is installed, as the POS module overrides `_compute_has_moves` with its own implementation that checks the outstanding balance directly. Root Cause: The `_compute_has_moves` method queries only `account.move `for partner matching. When a partner is referenced only at the account.move.line level, the partner is never picked up by this query, resulting in `has_moves = False` and the Due button remaining hidden. Fix: Replaced the EXISTS-based implementation with a UNION-based approach as the EXISTS implementation evaluated the query per partner row, whereas UNION processes all partners in a single batch query. Additionally extended the UNION to also include account.move.line partner matching, ensuring partners referenced only at the line level, are correctly detected and has_moves is set to True. Result: The Due smart button is now correctly visible for all partners with an outstanding balance, regardless of whether the partner is set at the journal entry level or only at the line level. owp = 6243562
This fix corrects a bug where refunded items appeared twice in POS receipts, leading to incorrect totals. The update ensures that refunded items are treated as a single line, resolving the issue and preventing double charges. This improves the accuracy of payment processing within the Point of Sale system.
Original PR description
**Steps to reproduce:** - Make a sale in the frontend - Refund it on the order in the backend - Reload the frontend page, the order is automatically set as the current one - Try to pay for it - There…
**Steps to reproduce:** - Make a sale in the frontend - Refund it on the order in the backend - Reload the frontend page, the order is automatically set as the current one - Try to pay for it - There are 2 lines on the ticket, and the total is thus wrong **Why the fix:** A line that has been refunded through the backend will appear twice in the receipt, causing it to be wrong. When loading the order from the backend, when we refresh the page after refunding it from the backend, we load the order and it's lines. The lines are found but they don't have any uuid set, so the pos sets one. Then at paying time, we load them again to check that nothing changed, but when loading the lines, we see that it does not have a uuid, as we did not write the frontend uuid to the backend yet. https://github.com/odoo/odoo/blob/0b17840fb3cc72935e1a6302a057fb55c253c498/addons/point_of_sale/static/src/app/store/pos_store.js#L1277-L1279 As we see we don't have a uuid on the line, we set it. The line is found again in the data in the snipped above. The line is then considered missing from the missingRecursive function, and when we try merge them with the existing lines, they don't have the same uuid so they are treated as different. This means we set 2 different uuids to a line that was in fact the same. The pos then sees 2 lines with 2 differents uuids, so it treats them as 2 different lines and we have to pay for both, even though they are the same and the second one should not have been added to the order and should have been ignored. Without this fix, the pos will think we don't have the line yet, even though we do, but just with another uuid so it will add it to the order even though it should not. We will then have the same line with two different uuid, so it will be considered as 2 different lines and both will be added to the receipt and have to be paid for. With this fix, the two lines now have the same uuid, and will be treated as the same line, as it should. opw-6235870
This update corrects a technical issue where a portal user's ID was incorrectly assigned as the author of system activity logs when orderpoints failed during a checkout process. This prevented accurate tracking of errors and could lead to access issues. The fix ensures that all system activities are properly attributed to OdooBot, improving log reliability and security.
Original PR description
Description of the issue/feature this PR addresses: When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `ProcurementException` and logs a…
Description of the issue/feature this PR addresses:
When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `ProcurementException` 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 18.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 `mail.activity` record 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-pr7 changes
Resolved issues and error corrections
This update resolves a technical issue where VoIP registration could fail due to idle sessions, causing error dialogs and preventing users from making calls. The fix ensures that the registration process is reliably restarted when a connection is lost, preventing the system from getting stuck and improving the user experience.
Original PR description
Leaving a session open and idle (page open, no activity at all) eventually pops an error dialog: UncaughtPromiseError > RequestPendingError REGISTER request already in progress, waiting for final…
Leaving a session open and idle (page open, no activity at all) eventually pops an error dialog:
UncaughtPromiseError > RequestPendingError
REGISTER request already in progress, waiting for final response
at Registerer.register (sip.js)
at Registerer.register (registerer.js)
at UserAgent.attemptReconnection (user_agent_service.js)
When the WebSocket transport drops while a REGISTER is in flight (which happens on an idle tab: SIP.js sends a periodic re-REGISTER before the registration expires, and the socket may be closed by an idle timeout or by the machine going to sleep in the meantime), the final response never comes back. SIP.js only clears its internal `waiting` flag from the REGISTER response callbacks (onAccept/onReject/onRedirect); it is never reset on transport loss or request timeout. The Registerer is then stuck `waiting` forever, and every subsequent register() rejects with a RequestPendingError.
On top of that, our wrapper's register() did not return the SIP.js promise, and attemptReconnection() called it without awaiting, so the rejection escaped the surrounding try/catch and surfaced as an unhandled promise rejection. Worse, the WebSocket error was resolved right after, so the user appeared reconnected while VoIP registration was actually dead until the page was reloaded.
This commit makes register() recreate the underlying SIP.js Registerer when it is stuck `waiting` (a clean instance starts with waiting=false), and return the promise so callers can await it. attemptReconnection() now awaits it, so any rejection goes through the existing retry/back-off logic instead of bubbling up as an uncaught error.
The recreation is intentionally conditional: disposing a healthy registerer would send an unregister (REGISTER expires=0) racing with the fresh register (expires=600) and could leave us unregistered, so we only recreate when a request is actually stuck.This update resolves an issue where a JSON decoding error could occur when downloading ETA invoice PDFs. A recent change introduced a workaround, but a new error type wasn't being caught. This fix adds a catch block to properly handle the `json.JSONDecodeError`, ensuring stable invoice processing.
Original PR description
When we download the ETA invoice PDF, a JSONDecoderError can happen when calling the json() method on the request. This error is properly caught by Odoo : https://github.com/odoo/odoo/blob/7a9a340e0dbac470c4bea3f8ce8a32e55f3e82e6/addons/l10n_eg_edi_eta/models/account_edi_format.py#L58-L60 However, the following commit introduced a monkeypatch to handle errors when the simplejson library is installed : 2435fe76eec1fc4320ef71726fc7f16ece653a32 If we meet the conditions, the original error is replaced by a json.JSONDecodeError which is not caught during the previous process. We propose to add this error to the catch block. This modification was inspired by the commit d483dac144a9caf84c44b9d8d394ea327ca87cfe. opw-6266862 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where order totals and refund amounts were incorrectly calculated after tax changes or refunds were processed in Point of Sale. The fix ensures historical order prices are preserved, providing accurate totals for both paid orders and refunds. This improves the reliability of financial reporting within the POS system.
Original PR description
Steps to reproduce 1. Create a product at $30 with a 15% tax-excluded tax (total = $34.50) 2. Sell and pay the order 3. Edit the tax and toggle price_include = True 4. Open POS, go to Orders > Paid —…
Steps to reproduce 1. Create a product at $30 with a 15% tax-excluded tax (total = $34.50) 2. Sell and pay the order 3. Edit the tax and toggle price_include = True 4. Open POS, go to Orders > Paid — the order total shows $30 instead of $34.50 5. Click Refund — the refund total also shows $30 instead of $34.50 Issue https://github.com/odoo/odoo/blob/130c5266e0fc37f64f58f67b44c84130643bec20/addons/point_of_sale/static/src/app/store/models.js#L1067-L1090 get_all_prices() recomputes prices from price_unit using current tax objects, ignoring price_subtotal/price_subtotal_incl already serialised in the order JSON. When price_include changes on a tax after an order is paid, the historical total is lost. https://github.com/odoo/odoo/blob/130c5266e0fc37f64f58f67b44c84130643bec20/addons/point_of_sale/static/src/app/store/models.js#L1580-L1608 this.locked was assigned after the orderlines loop, so Orderline.init_from_JSON could not use it to distinguish paid from draft orders. https://github.com/odoo/odoo/blob/130c5266e0fc37f64f58f67b44c84130643bec20/addons/point_of_sale/static/src/app/screens/ticket_screen/ticket_screen.js#L653-L668 _prepareRefundOrderlineOptions passed price_type: "automatic" which triggered a fresh get_all_prices() with current taxes, producing the same wrong total on refunds. Solution Move this.locked assignment before the orderlines loop. When locked, pin price_subtotal/price_subtotal_incl from JSON in Orderline.init_from_JSON and return them early in get_all_prices(), scaling by qty/lineQty so per-unit display calls (get_all_prices(1)) remain correct. Read amount_total/amount_tax from JSON and return them directly in get_total_with_tax()/get_total_tax() for locked orders. Carry price_subtotal/price_subtotal_incl in the refund detail snapshot and inject them (scaled by partial-refund ratio) as extras on the refund orderline. opw-6097256
This update resolves an issue causing blank content in snail mail documents during validation. The problem stemmed from a recent change that incorrectly used a PDF source. This fix ensures the correct PDF is utilized, resulting in properly formatted mail documents.
Original PR description
This commit fixes a regression introduced in odoo/odoo@dc72061383a4 where, while fixing the calls to actually merge page on a pdf writer instead of the reader, the wrong pdf was used as a source.
This update fixes an error in the VAT balance calculation within the l10n_uy module for Uruguay. The previous formula was inaccurate, leading to incorrect reporting. This change ensures accurate VAT reporting, aligning with local tax regulations.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_uy 2. Go to tax report and see the formula of the VAT balance that is incorrect ### Reason to introduce the fix: Correct the formula to display the right amount. opw-6261211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where cron workers weren't efficiently managing database connections. By introducing new configuration variables for cron workers, we can now limit their registry usage, reducing memory consumption and improving overall performance. This ensures Odoo runs smoothly under heavy background workloads.
Original PR description
The configuration option `registry_lru_size` does not exist and does not work at all in recent versions. Defining odoo-specific environment variables to handle: - ODOO_REGISTRY_LRU_SIZE: the default registries size - ODOO_REGISTRY_LRU_SIZE_CRON: overwrite for cron workers Cron workers have often a different workload than HTTP workers and we may set a different limit there. If the limit is lower than the number of databases, a cron job will not reuse registries because it cycles through all known ones - in such cases, we can set a lower limit to keep the memory lower. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a bug that caused a 'divide by zero' error when generating Jordanian e-invoices with invoice lines having a quantity of zero. The fix ensures invoices with zero quantities can now be successfully sent to JoFotara, improving invoice processing reliability. This resolves an issue reported in opw-6262469.
Original PR description
Steps to reproduce: - Ensure Jordanian e-invoicing is installed - Create an invoice where one of the lines has a 0 quantitiy - Send the e-invoice JoFotara (Jordan EDI) Current Behavior: You will get a divide by 0 error popup Expected Behavior: No error and the invoice is sent opw-6262469