Daily updates from Odoo
Wednesday, June 10, 2026
323 changes
18 changes
Enhancements to existing features
This update improves the D300 VAT report for Romanian businesses. The report's name has been changed to better align with local regulations and reporting requirements. This ensures accurate and compliant financial reporting for our Romanian customers.
Original PR description
Rename VAT report fom Romania task-5423935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252511
This update improves the generation of the D300 VAT report for Romanian businesses, aligning with the latest requirements from the ANAF (Romanian tax authority). It now creates an XML file to streamline the reporting process and ensure compliance with current regulations.
Original PR description
Rename VAT report fom Romania and generate XML file to complete flow for D300 return complying with the latest ANAF specifications. https://static.anaf.ro/static/10/Anaf/Declaratii_R/300.html task-5423935 Forward-Port-Of: odoo/enterprise#109849
Resolved issues and error corrections
This update fixes an issue where self-order kiosk payments would remain stuck if a user clicked the back button. Now, a confirmation dialog appears, allowing users to cancel the payment before returning to the previous screen. This ensures a smoother and more reliable payment experience for self-order transactions.
Original PR description
Before this commit, when a cash machine payment was in progress in the self order kiosk, clicking the back button would not cause the payment to be cancelled, leaving the cash machine stuck. After this commit, upon clicking the back button a dialog shows asking the user if they want to cancel their payment, and if so the transaction is cancelled before sending the user back. task-6276665 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update significantly speeds up the process of adding and removing participants from marketing campaigns. By optimizing the underlying code, the sync time has been reduced from over 51 seconds to just 0.65 seconds, even with a large campaign of 115,000 participants. This improves the overall performance and responsiveness of the marketing automation features.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#119589 Forward-Port-Of: odoo/enterprise#117656
This update fixes an issue where payslips weren't correctly generating worked day lines for employees using attendance-based work schedules. The change ensures that all employees, regardless of their flexible working arrangement, receive accurate wage calculations based on their attendance records. This improves payroll accuracy and reporting.
Original PR description
### **Steps to reproduce:** - Install Payroll and Attendance apps. - Create an employee with a flexible working schedule and work entry source as attendance. - Create an attendance record for this…
### **Steps to reproduce:** - Install Payroll and Attendance apps. - Create an employee with a flexible working schedule and work entry source as attendance. - Create an attendance record for this employee. - Create and compute a payslip for this employee. ### **Observed Behavior:** Worked Day lines are not generated, and Basic Wage is calculated as 0. ### **Expected Behavior:** Worked Day lines should be populated based on attendance records. ### **Root Cause:** During payslip computation, [_compute_worked_days_line_ids](https://github.com/odoo/enterprise/blob/4339010eb1e1633a67573d08e032f3922b0bec49/hr_payroll/models/hr_payslip.py#L1846) only generated work entries for versions having a `resource_calendar_id` at [1]. As a result, fully flexible employees without a working schedule were excluded from work entry generation, preventing worked day lines from being computed. [1]- https://github.com/odoo/enterprise/blob/4339010eb1e1633a67573d08e032f3922b0bec49/hr_payroll/models/hr_payslip.py#L1890-L1898 ### **Fix:** Remove the `resource_calendar_id` filter when calling `generate_work_entries` in `_compute_worked_days_line_ids` so work entries are also generated for fully flexible employees using attendance-based work entries. **opw-6146452** Forward-Port-Of: odoo/enterprise#117409
A recent test was failing due to a minor issue with how content snippets were being dropped onto the website builder. This fix ensures snippets are consistently placed in the correct dropzone, resolving the test failure and improving the stability of the website builder functionality. The change is a simple correction to the test setup.
Original PR description
Test that was testing that we cannot drop some snippets in a table of content sometimes failed due to the fact that it could sometimes drop in the wrong drop zone. This happens because 2 dropzones are really close to each other: <--- dropzone ---> [1] <--- toc start ---> <--- dropzone ---> [2] <--- section ---> <--- dropzone ---> [3] ... <--- toc end ---> When we move the snippet thumbnail to the dropzone [2], and drop it by calling `getDragHelper` it recomputes the position of the thumbnail, and sometimes it may drop the snippet in the first dropzone [1], breaking the test flow. We fix it by moving the snippet to the third dropzone [3], where it surely will drop, as there are no neighboring dropzones. runbot-241922 Forward-Port-Of: odoo/odoo#268473
This update clarifies the reporting of employee hours by renaming a confusing column from "Expected Hours" and "Theoretical Hours" to "regular hours". This change ensures that the report accurately reflects the hours an employee is scheduled to work, improving data understanding and reporting accuracy.
Original PR description
The column name "Expected Hours" and "Theoretical Hours" is confusing since it doesn't show the hours that the employee is supposed to work according to their contract, just the number of hours that are not considered overtime. This commit renames the column to better reflect the measure that is shown. task-6123642 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#262230
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
Features or functions removed from Odoo
This update corrects a minor issue where a file was incorrectly added to the Odoo account_peppol module. The file was a byproduct of a previous porting effort and a discrepancy in a related version. This change ensures the system operates with the correct configuration.
Original PR description
It was added in the FW-port of the PDP PR by the cherry-picking since there was a diff in the file in saas-19.2 (where the file still existed). task-None
13 changes
Resolved issues and error corrections
This change removes a test that was failing due to inconsistencies in how German date/time formats are handled by Chrome and the underlying Unicode CLDR data. The test was tied to a specific Chrome version and a recent update to the ICU library (which relies on CLDR) has introduced a conflict. This ensures the duration parsing functionality continues to work correctly across different Chrome versions.
Original PR description
Cause: ---------------------------------------- Commit 121806b57816d0fbd48b5538d2a8beae35905d99 added a test verifying that the duration in German is correctly recognized. In the test, "2 Std. 30…
Cause: ---------------------------------------- Commit 121806b57816d0fbd48b5538d2a8beae35905d99 added a test verifying that the duration in German is correctly recognized. In the test, "2 Std. 30 Min. 45 Sek.", was supposed to be recognized as 2.5125 hours. But on some browser versions it fails, as in the latest Chrome version. This is because we use `DurationFormat()` to get the localized units. This method is supported by all browsers and will use the browser's data to get the translations. This data comes from [Unicode CLDR](https://cldr.unicode.org/) which is updated regularly. We would need to change the test depending on the Chrome version, so we just delete it. It appears that for German hours the CLDR definitions have historically shifted between two distinct representations: "Std." and "h" As an example: - CLDR 47: https://github.com/unicode-org/cldr-json/blob/16f6b8578ba5fe98959034706f337674f816fc3f/cldr-json/cldr-units-full/main/de/units.json#L3526-L3527 - CLDR 48: https://github.com/unicode-org/cldr-json/blame/4d06be52b51bb2f75688d0abe55c52a66afed790/cldr-json/cldr-units-full/main/de/units.json#L3916-L3917 So the test fails in CLDR 48 but succeeds in CLDR 47. As the latest version of `ICU` (used by browsers) updates its dependency to CLDR 48 ([src](https://unicode-org.github.io/icu/download/78.html)) this explains why the latest Chrome version makes the test fail. runbot-939543
This update resolves a performance issue within the tests for the 'Discuss' feature. The change optimizes a database query, resulting in faster test execution times. This improvement ensures the stability and responsiveness of the Discuss functionality.
Original PR description
runbot-243772 https://github.com/odoo/enterprise/pull/119886
This update addresses a performance issue within the Odoo Discuss module, specifically related to counting data. The change optimizes a database query, resulting in faster response times and a smoother user experience. This improvement ensures the Discuss feature remains efficient and reliable for all users.
Original PR description
runbot-243772 https://github.com/odoo/odoo/pull/269111
This update fixes an issue where undoing the auto-plan feature would reset a shift's allocated workload hours, leading to inaccurate reporting. The change preserves the original workload value during undo, ensuring that shift allocations remain consistent and reliable. This improves the accuracy of resource planning.
Original PR description
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation…
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation triggers recomputation of allocated_hours, causing the shift to lose its original workload value. Current Behaviour --- When resource_id is set to False during undo: - _compute_allocated_hours is triggered (depends on resource_id) - _compute_allocated_percentage is triggered (depends on allocated_hours) - Both fields are recalculated, potentially changing allocated_hours from its pre-assignment value Expected Behaviour --- Undoing auto-plan should preserve allocated_hours at its pre-assignment value while allowing allocated_percentage to adapt to the new context (open slot vs assigned resource). Fix --- Use protecting context manager in action_rollback_auto_plan_ids to prevent allocated_hours from being recomputed when resource_id is removed. This allows allocated_percentage to recalculate naturally based on slot duration while keeping allocated_hours stable. task - 4952149 Forward-Port-Of: odoo/enterprise#119772 Forward-Port-Of: odoo/enterprise#102864
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 form submission process. It ensures a stable login experience for Safari users in private browsing.
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 the default mail scheduler. The fix ensures emails are queued instead of processed synchronously, preventing savepoint errors during the import process. This improves the reliability of attendee imports.
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 unnecessary calculations, resulting in a 98% reduction in processing time for complex employee leave scenarios. This improves the 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 removes a duplicate button from the channel management interface. Previously, users encountered errors when attempting to copy channels, and this feature offered little value. This change simplifies the channel creation process and resolves a technical issue.
Original PR description
duplicating channels does not provide much value. when you try to copy channel error comes like `you do not have enough rights to access the field ai_agent_id on Discussion Channel (discuss.channel).` now we are remove the duplicate button from channels form view cog menu as its does make sense to use it there at all. task-5494736 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269153 Forward-Port-Of: odoo/odoo#268999
This update corrects a bug in the sale details report that previously failed to include discounts applied through loyalty programs. Now, the report accurately displays the total discount amount, including those generated by the loyalty program, ensuring accurate sales reporting. This resolves an issue impacting all users utilizing the loyalty program.
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#267753
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.
10 changes
Enhancements to existing features
This update introduces a time limit for query profiling within Odoo. By tracking query execution times and periodically committing this data, we're improving the performance and reliability of the profiler tool. This ensures that profiling data is captured efficiently and doesn't negatively impact system performance.
Original PR description
Modify the query collector so that it add an entry before the query runs and updates the time after it runs. use the async collector periodic sampling to commit the profiler after a time limit. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268467 Forward-Port-Of: odoo/odoo#215034
Resolved issues and error corrections
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 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
5 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
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
15 changes
New functionality added to Odoo
This update introduces a new wizard within the Odoo Enterprise system that guides users through the process of preparing and submitting their VAT returns. The wizard generates the necessary XML files and displays any errors or warnings, allowing users to easily download and submit their VAT returns directly. This simplifies the VAT reporting process and improves accuracy.
Original PR description
- Add a submission wizard providing instructions for users on how to submit the VAT return. - Show XML generation errors and warnings in the wizard. - Allow users to download the XML directly from the wizard. task-5403651
Enhancements to existing features
This update refines how Odoo calculates worked days for payroll, ensuring more accurate and reliable pay calculations. The changes address a previous calculation error and improve the overall stability of the payroll process. This update primarily impacts the HR and Payroll modules.
This update clarifies how half-day work periods are displayed on payslips. Previously, half-days were grouped with full days, making it difficult to understand total work hours. Now, half-day entries are clearly separated, providing a more accurate and transparent view of employee earnings.
Original PR description
In order to clearly distinguish work days that extended full day or half day, the worked days under the payslips will not display both entries as separate types with the half days flagged Task: 5975762 Forward-Port-Of: odoo/enterprise#118869 Forward-Port-Of: odoo/enterprise#112328
This update streamlines the configuration of delivery methods (BPost, Easypost, Envía, Sendcloud, Shiprocket, Starshipit) by consolidating settings within the main Stock configuration. This simplifies the user interface and improves overall usability for managing delivery options.
Original PR description
easypost, envia, sendcloud, shiprocket, starshipit -------------------------------------------------------------------------------- These delivery connector modules no longer need to define their own Inventory configuration entries and views since delivery methods and connectors are now managed from a single place in the Stock configuration. This cleanup removes obsolete views and settings so users can configure all delivery methods from a single, cleaner interface, improving overall usability. Community PR:- https://github.com/odoo/odoo/pull/242503 Upgrade PR:- https://github.com/odoo/upgrade/pull/9208 TaskId:- 5380595
This update streamlines the Discuss meeting experience by adding a 'Your Meeting is Ready' banner and simplifying controls for adjusting the view and inviting participants. The changes improve usability and make it easier to start and manage meetings within Discuss.
Original PR description
Rework the in-call/meeting experience in Discuss: - Add a "Your Meeting is Ready" banner shown while alone in a call, surfacing the permanent share link and a shortcut to invite people; it hides once…
Rework the in-call/meeting experience in Discuss: - Add a "Your Meeting is Ready" banner shown while alone in a call, surfacing the permanent share link and a shortcut to invite people; it hides once another participant joins. Starting a "New Meeting" no longer auto-opens the invite panel. - Add an "Adjust view" dialog to pick the meeting grid layout (auto, tiled, spotlight, sidebar, discuss); the choice is persisted in user settings. Layout actions (Adjust view, Picture in Picture) move into a "More" menu in the call bar, while Fullscreen keeps its own corner button and Exit Fullscreen sits next to Chat in fullscreen. - Mirror the meeting share link in the address bar while in a call and restore the regular Discuss URL once it ends. - Starting a meeting now enters fullscreen and auto-hides (unpins) the meeting channel from the sidebar. - Open the invite UI as a single centered dialog everywhere (openChannelInvitationDialog); the member-list button reads "Add People" in the meeting view. Drop the "Generate new invite link" button. Along the way, tidy up the Discuss sidebar and messages: - Only show the Bookmarks mailbox when it holds at least one message. - Move "View hidden conversations" out of the sidebar (still reachable from the command palette) and restyle the "New Meeting" button. - Keep fewer inline message quick actions (3 instead of 4): Copy Text and Copy Link move to the expanded actions menu, and "Copy Link" is renamed "Copy Message Link". - Simplify the meeting channel name, e.g. "Meeting, Jan 1". task-6260047
This update enhances the visual presentation of the holiday attest report within the Odoo Enterprise system. The changes focus on reworking the layout to improve readability and clarity for users reviewing employee holiday information. This ensures accurate and easily understandable reports for payroll and HR processes.
Original PR description
This commit reworks the layout of the holiday attest report. task-5936242
This update enhances the Odoo Enterprise integration with Google Reserve by simplifying the synchronization process for users. It includes clearer troubleshooting guidance and prevents accidental deletion of Google Reserve merchants when linked to synchronized appointment types. This improves the overall user experience and data integrity.
Original PR description
…UI/UX Make it easier for end users to synchronize their appointment type with Google Reserve by adding links to the documentation as well as more complete banner messages for troubleshooting. Also prevent google.reserve.merchant deletion if they are used inside a synchronized appointment.type. Task-6148700
Resolved issues and error corrections
This update streamlines the payment refresh button in the Odoo Enterprise system. Previously, the button was always visible, leading to unnecessary system calls. Now, it only appears for payments that are actively being processed (pending or unsigned), optimizing performance and reducing strain on the system.
Original PR description
… batches The refresh button was always shown, which could cause unnecessary calls to OdooFin if the payment is finalised (accepted, rejected or canceled). With this change, the button is shown only for payments in progress (pending or unsigned). task-6103900 Forward-Port-Of: odoo/enterprise#113182
This update fixes an issue where flexible schedules were incorrectly calculating work hours, leading to inaccurate payroll totals. The change decouples the hour splitting logic, now relying on specified daily hours instead of attendance hours, ensuring accurate half-day and full-day calculations.
Original PR description
Steps: - Create half day off for an employee - Create a full day off of the same type - Create a payslip for the employee Issue: - Due to the lack of attendance hours in the flexible schedules, the _get_work_hours_split_half is unable to split half day and full days work entries of the same type. - Half worked days will be rounded up which affects the total number of work days in a month Solution: The approach was to decouple the work_hours_split_half functionality from the attendance hours and rely on the specified hours_per_day instead. This accurately splits half and full days. Task: 6253675 Forward-Port-Of: odoo/enterprise#118968 Forward-Port-Of: odoo/enterprise#118836
This update refines the calculation of worked days for payroll, addressing inconsistencies and improving accuracy. The changes enhance the reliability of payslip generation, ensuring employees are paid correctly based on their actual working hours. This update impacts the core payroll functionality.
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
Features or functions removed from Odoo
This update removes jQuery, a legacy JavaScript library, from all Odoo Enterprise modules. This simplifies the codebase, improves performance, and reduces potential security vulnerabilities. The change was driven by a community contribution and aligns with Odoo's ongoing efforts to modernize its technology stack.
Original PR description
[REM] *: remove jQuery from all assets *: knowledge, pos_iot, pos_self_order_iot, sign This commit removes jQuery in every asset where it was still included and clean comments still referencing old jQuery logic. Precision: `web._assets_jquery` can be removed from `_get_url_to_cache` as it's not used anymore since odoo/enterprise@c120aa2a7e8. Community PR: odoo/odoo#250982 task-5187485
Code cleanup and technical improvements
This update refactors internal code within several Odoo modules to utilize a new 'plugin' architecture. This change enhances modularity and flexibility, allowing for easier future updates and integrations within the Odoo platform. It primarily impacts the underlying structure of various modules, improving maintainability and scalability.
This update streamlines the Odoo IoT device model by removing redundant information like manufacturer and device subtype. This change simplifies the underlying code, making it easier to maintain and update, which ultimately reduces development time and potential issues.
Original PR description
This commit aims to simplify the IoT device model by removing unnecessary data such as: - manufacturer, - device subtype (was only used for printers), As usual, the goad is to reduce complexity of the code to improve maintainability. see odoo/odoo#258127
13 changes
Enhancements to existing features
This update enhances the Romanian VAT reporting process within Odoo Enterprise. It renames the VAT report and generates an XML file, aligning with the latest requirements set by the ANAF (Romanian tax authority). This ensures accurate and compliant D300 returns.
Original PR description
Rename VAT report fom Romania and generate XML file to complete flow for D300 return complying with the latest ANAF specifications. https://static.anaf.ro/static/10/Anaf/Declaratii_R/300.html task-5423935
This update ensures Odoo's GSTR-3B and GSTR-2B reports accurately reflect purchase composition supplies transactions, aligning with recent government regulations. The changes create dedicated lines for these supplies in the reports, improving reporting accuracy and compliance for our Indian customers.
Original PR description
As a new GSTR section for purchase composition supplies has been introduced, the related report domains also need to be updated accordingly. With this commit: GSTR-3B domains are updated to properly include purchase_composition_supplies transactions in the relevant report section. GSTR-2B now includes a separate line for composition supplies, aligned with the government utility format. task-6239870
Resolved issues and error corrections
This update resolves an issue in the Data Cleaning app where record IDs were incorrectly summed and displayed alongside group names, causing truncation and misrepresentation of data. The fix removes the default 'sum' aggregator for integer fields, ensuring group headers accurately show the count of records.
Original PR description
## Issue In the *Data Cleaning* app, when grouping records, the record IDs are summed up and appear right next to the name of each group, which: 1. truncates the name and count of the groups 2. does…
## Issue
In the *Data Cleaning* app, when grouping records, the record IDs are summed up and appear right next to the name of each group, which:
1. truncates the name and count of the groups
2. does not make sense (summing up IDs is pointless)
<img width="709" height="374" alt="6166623-before" src="https://github.com/user-attachments/assets/9d80b1ec-49c0-4b7f-8c6e-53846f9e433e" />
## Steps to reproduce
1. Install *Data Cleaning* (`data_cleaning`)
2. In Data Cleaning > Configuration > Field Cleaning, create a new rule (or edit an existing one):
- Any name
- Model: *Contact*
- Rule:
- Field to Clean: *Name (Contact)*
- Action: *Set Type Case* - Case: *All Uppercase*
4. Click the *Clean* button in the upper left corner
5. In Data Cleaning > Field Cleaning, group the records by any field (e.g., *Field*)
6. **The name of the group (_Name (Contact)_) is truncated, making it and the record count unreadable. This is due to the sum of _Record ID_ being displayed in the same row, even though that information is irrelevant.**
## Cause
The *Record ID* (`res_id`) field is an Integer field defined [here](https://github.com/odoo/enterprise/blob/3603afdd5c0d19c9276f3855156be4040ab5717d/data_cleaning/models/data_cleaning_record.py#L20). By default, Integer fields have the `sum` aggregator:
https://github.com/odoo/odoo/blob/681610c002a310f1c73fc2e5bec8d3dae27bc4a7/odoo/orm/fields_numeric.py#L17-L23
This causes the IDs to be summed up and appear in the group headers.
## After
<img width="740" height="370" alt="6166623-after" src="https://github.com/user-attachments/assets/a42d8f58-06dc-4308-8b6f-1ab09e8034f8" />
related: https://github.com/odoo/odoo/pull/265163
opw-6166623This update significantly speeds up the process of adding and removing participants from marketing campaigns. By optimizing a key database function, the system now completes this task in just a fraction of the time – reducing it from over 51 seconds to less than a second. This improvement will result in quicker campaign updates and a smoother user experience.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#119589 Forward-Port-Of: odoo/enterprise#117656
This update resolves an issue where Peruvian tax reports couldn't generate closing entries after the 18.3 update. The fix creates a specific tax report variant for Peru, ensuring accurate VAT calculations and restoring the automated closing entry process for Peruvian businesses. This prevents errors and allows for proper tax account configuration.
Original PR description
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that…
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that you need a Return Type in order to make a Closing Entry using the Validate button Additionally, using the Generic Tax Report by default creates a risk in Multi-VAT environments, as it mixes taxes from all countries instead of isolating Peruvian taxes ### Cause The new 18.3 accounting workflow requires at least one active Return Type associated with a country-specific report variant to display the Return options and process the closing entry Peru was relying on the Generic Tax Report, without a dedicated report variant No Return Type was configured, which blocked Odoo's automatic VAT closing workflow and prevented the system from prompting the user to configure the required closing accounts ### Steps to reproduce - Install `l10n_pe_reports` and `accountant` - Switch to a PE Company - Go to the Tax Report Before the fix, no Returns button is available for any of the existing reports, making it impossible to use Odoo's automatic process to configure the tax accounts and trigger the closing entry ### Notes This is fixed by creating a dedicated Peruvian tax report variant directly in Enterprise that inherits from the generic tax report A custom handler is added to force the domain filtering on Peruvian taxes only, and a corresponding Return Type is defined to restore the full closing entry process safely opw-5978673 Forward-Port-Of: odoo/enterprise#117891
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must be before the end time, ensuring correct shift template creation.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
This update resolves an issue where the barcode inventory count feature would fail when using archived units of measure. The fix ensures that archived UoMs are correctly included in the inventory count cache, allowing accurate counts to be performed. This prevents errors during physical inventory adjustments.
Original PR description
### Steps to reproduce: - In the settings enable: "Units of Measure & Packagings", "Storage Locations" - Create a product in units and register 1 unit in stock - Inventory > Operations > Adjustments…
### Steps to reproduce: - In the settings enable: "Units of Measure & Packagings", "Storage Locations" - Create a product in units and register 1 unit in stock - Inventory > Operations > Adjustments > Physical Inventory - Select your line and request a count > Set Current Value - Inventory > Configurations > units of measures > UOM categories - Select unit and archive it - Go to the barcode app > Click Count inventory ### > Owl error: Uncaught promise ### Cause of the issue: Since the uom used on the quant is archived, it is not found by the search used to fill the barcodeCache: https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/models/stock_quant.py#L104-L106 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/models/barcode_model.js#L37-L39 However, if the uom is not present in the barcode cache the `BarcodeQautnModel` will fail to createLinesState whihc raises a missing error: https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/models/barcode_quant_model.js#L712 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/lazy_barcode_cache.js#L107-L110 opw-6250090 Forward-Port-Of: odoo/enterprise#118987 Forward-Port-Of: odoo/enterprise#118813
This update resolves a potential error in the Hong Kong payroll calculations. Specifically, it now checks for a missing resource calendar or zero hours per week, preventing a division-by-zero issue that could have disrupted payroll processing. This ensures accurate and reliable payroll calculations for Hong Kong businesses.
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 fixes an issue where barcode scanning incorrectly displayed delivered quantities on sales orders. The problem stemmed from how the system selected lines during delivery updates, leading to inaccurate order fulfillment. The fix ensures correct quantity updates when using barcode scanning with lots.
Original PR description
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities. ## Steps to replicate: - Install Sales and Barcode (no demo data). - Enable Lots & Serial…
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities.
## Steps to replicate:
- Install Sales and Barcode (no demo data).
- Enable Lots & Serial Numbers in settings.
- Create Test Product with Tracking by Lots.
- Go to Inventory > Products>Lots & Serial Numbers and create 3 lots for the product.
- Update each lot’s on-hand quantity to 10 from the product page.
- Create and confirm a Sales Order for the product (lines: qty 3 and 2 units).
- Open the delivery in the Barcode app:
- Scan lot 2 > increase qty to 3 using +1 button
- Scan lot 3 > increase qty to 2 using +1 button
- Validate and go to the sale order.
## Observed Behavior:
The sale order delivered quantities are flipped and a backorder is created even though the quantity for the product is satisfied.
## Root cause:
The issue occurs because when a sales order is confirmed, the system defaults to
using lot 1 on the delivery receipt. When a user scans lot 2, the `_processBarcode` function is triggered, which calls `_findLine` at [1] to select the appropriate line on the receipt.
As the loop in `_findLine` iterates through `pageLines` with values like:
```
[{display_name: "Test product", quantity: 3, lot_id: { name: 'lot1' }},
{display_name: "Test product", quantity: 2, lot_id: { name: 'lot1' }}]
```
During the first iteration, `foundLine` is set at [2] for the line with quantity 3 . Since the subsequent if condition is not satisfied, the loop hits the continue block at [3].
On the next iteration, the line with quantity 2 causes `foundLine` to be overwritten at [2], and the continue block is executed again at [3].
This results in the line with quantity 2 being selected as the line to update at the end of the function.
When the user manually increases the quantity to 3, the line that originally required quantity 2 is updated and fulfilled.
Later, when lot 3 is scanned, the line that required quantity 3 is selected for update, and manually increasing the quantity to 2 before validating the order leads to a backorder and causes the delivered quantities to be flipped.
[1]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1335-L1337 [2]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1690-L1699 [3]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1727-L1729
## Solution:
Avoid grouping lines from different moves unless using batch transfers. This ensures that backorders are not created when the barcode lines are fulfilled.
opw-5423943
Forward-Port-Of: odoo/enterprise#118085
Forward-Port-Of: odoo/enterprise#109032This 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
13 changes
Enhancements to existing features
This update introduces a new 'PINT' layer in the account_edi_ubl_cii module, bridging the gap between UBL and BIS3 invoice formats. This enhancement supports compliance with European regulations and standards, particularly those related to PEPPOL, by providing a standardized layer for invoice processing and data exchange.
Original PR description
Add the layer PINT between UBL and BIS3. task: 5890887
This update moves a key test case related to UBL (Universal Business Language) billing in Belgium (account_edi_ubl_cii) to the new testing framework. This ensures better test coverage and reliability for our UBL billing processes, improving the overall quality of the system. The change was prompted by a previous update to the test suite.
Original PR description
Move test introduced by https://github.com/odoo/odoo/pull/265261 to the new test suite in account_edi_ubl_cii --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This update improves the security of our bank account import process. It now only uses bank accounts designated as 'trusted' (with `allow_out_payment=True`) when matching partner information. This prevents potential errors and ensures data accuracy during bank account retrieval.
Original PR description
Restrict the matching domain to bank accounts with `allow_out_payment=True` so that only trusted bank accounts are used when retrieving a partner from a bank account number
This update fixes an issue where product matching by name was incorrectly associating products across multiple lines in imports. The fix adds a necessary cache key, ensuring that products are matched accurately based on their unique characteristics, preventing incorrect product assignments during import processes. This improves data integrity and import accuracy.
Original PR description
**PROBLEM** When retrieving a product by name, there is no cache_key for the search_method criteria. This leads to the cache_key frozendict being an frozen dict with None values. This means, once we retrieve a first product with the search_method criteria, all following product will match its cache_key, so we ends up associating a product to all subsequent lines, even if they don't have anything in common. **STEP TO REPRODUCE** 1. Create a product with the name: "CASTELTORRE MERLOT DELLE VENEZIE 75CL 10,5i" (it's important the name is not exactly matching) 2. Import the xml which is attached to the bug fix ticket. 3. Notice the product column on all the lines after a certain point have the CASTELTORRE product, even though the corresponding line in the ubl is for another product. opw-6227280
This update fixes a minor inconsistency in Polish VAT invoice calculations (l10n_pl_edi) related to unit prices. Increasing the precision of the unit price field ensures that the total without tax accurately reflects the invoice amount, aligning with FA(3) format requirements. While technically valid, this change improves invoice accuracy and data consistency.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice with a unit price of 10.005 and qty of 2. 2. Send the invoice to ksef. 3. Open the xml and notice P_9A (unit price) is 10.00 and P_11 (total without tax) is 20.01 Which is inconsistent (10.00 * 2 =/= 20.01). This PR increase the decimal places of P_9A to 8 digits which is the maximum allowed by the FA(3) format. Note that Ksef doesn't verify the untaxed unit price * quantity = total without tax, so the invoice we send are technically valid. However, it's best to generate invoice where the numbers add-up. opw-6203896
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-pr1 change
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.