Daily updates from Odoo
Tuesday, June 23, 2026
65 changes · master
New functionality added to Odoo
This change adds a standard file to the Odoo repository that helps with version control and blame tracking. It mirrors the configuration used in the main Odoo repository, improving consistency and streamlining the development process. This is an internal update with no direct impact on users.
Original PR description
Currently an empty placeholder, but mirrors odoo/odoo
This update adds support for popular food delivery services like Talabna, Mandoob, and DiDi Food, expanding Odoo's reach to new markets. The changes also include backporting integrations for existing delivery providers, enhancing the platform's capabilities for restaurants and delivery businesses. This improves the user experience by offering more delivery options.
Original PR description
In this commit: - We are introducing new delivery providers like Talabna, Mandoob, Snoonu, DiDi Food and Zyada for different countries and backporting Radyes, ToYou, The Chefz, InstaShop and Smiles. Task-6263289,6263272,6263203,6263165,6310690 Forward-Port-Of: odoo/enterprise#121229 Forward-Port-Of: odoo/enterprise#119537
This update adds support for Belgium's new payroll regulations by mapping key codes (DMFA, eGov3, and salary categories) to the correct work entry types within the Odoo system. This ensures accurate and compliant payroll processing for Belgian businesses using the Enterprise edition.
Original PR description
Map DMFA codes, daily eGov3 codes, and salary categories to the new work entry types. Task: 6275946
This update consolidates SMS functionality into a new 'frontdesk_sms' module, improving organization and maintainability. It moves key SMS-related data and logic, and introduces a helper function to prevent code duplication, streamlining the frontdesk visitor management process.
Original PR description
In this PR we have moved all the sms related stuffs from **frontdesk** to **frontdesk_sms** Task-6068563
Enhancements to existing features
This update simplifies the process of creating company cars within the Odoo Enterprise system. It now automatically transfers information from the employee's existing car details to the company car creation form, eliminating a manual step. Furthermore, the quick create option has been removed, ensuring only authorized users can create and edit company car records.
Original PR description
This PR expected to pass input value from inventory car field in Employee Form to license plate field in create company car form and also remove quick create, only allowed create & edit task:6307500
This update implements the required NSSO reduction for elderly employees in Belgium (Brussels and Wallonia), aligning with recent regulations and ONSS guidelines. The changes improve the accuracy of these deductions, particularly regarding part-time worker calculations and wage caps. The update also addresses a critical issue with the µ calculation, ensuring it aligns with ONSS instructions for structural and target-group reductions.
Original PR description
Implements the NSSO elderly-worker reduction for Brussels (codes 7320) and Wallonia (8320/8321/8322), including the Wallonia 2023 reform and the 2026-04-01 hire-date sub-rule. Adds: * A monthly…
Implements the NSSO elderly-worker reduction for Brussels (codes
7320) and Wallonia (8320/8321/8322), including the Wallonia
2023 reform and the 2026-04-01 hire-date sub-rule.
Adds:
* A monthly salary rule producing an estimation of the quarterly G1
reduction prorated on the current slip, for payslip visibility.
* Dated hr.rule.parameter records holding the per-region bracket tables
(age_min, age_max, dmfa_code, G), the quarterly wage caps, and the
βg breakpoints.
* DMFAOccupationDeductionElderly in hr_dmfa.py: P = G × µ × βg per
matching bracket per occupation, with µ from declared service hours
and βg from the worker-level µ_global.
* Tests covering region/age/hire-date branching, the wage cap, part-time
µ rounding, and payslip-vs-DMFA parity.
Payslip estimation takes shortcuts that make it informational only: it
sums all worked-days hours instead of filtering DMFA service codes,
extrapolates one month × 3 instead of aggregating the real quarter,
uses the slip's own µ as µ_global, ignores multi-occupation aggregation,
checks the wage cap on ONSS_BASE × 3 instead of the proper ss_quarter,
and prorates the quarterly result flatly across months.
Shared bracket / βg / age helpers live on hr.payslip rather than in
hr_dmfa.py because the salary rule needs them at slip computation time
(before any DMFA export exists)
task - 6131498This update enhances the management of timesheet rules by introducing an archiving feature. Instead of deleting inactive rules, they can now be archived, maintaining a historical record and simplifying the timesheet configuration. This improves organization and reduces the need for frequent deletions.
Original PR description
This PR adds the "active" field to the "aw.rule" model, which allows to archive rules instead of having to delete them. no-task
This update introduces a new NISS (National Identification Number) field to the Belgium salary configurator, aligning with local regulations. Previously, the identification_id field was removed, and now the system accepts an empty NISS value during validation. This ensures accurate employee data matching within the Odoo system for Belgian payroll.
Original PR description
[IMP] l10n_be_hr_contract_salary: NISS in salary configurator
1 - For Belgium salary configurator, identification_id field is deleted and NISS field is added
1.1 - NISS field is added to the version of l10n_be_hr_payroll as a related field (from employee), salary configurator applies on version and makes the matching
2 - Empty NISS in validation is accepted as well now (in the UI of salary configurator)
task - 6147359This update enhances the Odoo Enterprise mail system by incorporating new syntax for OWL 3 (part 3) properties. This improves the system's ability to handle complex data and relationships within Odoo's various modules, particularly those related to documents, accounting, and HR. It’s an important update to ensure continued compatibility and functionality.
Original PR description
Enterprise counter-part. task-6255532 https://github.com/odoo/odoo/pull/270123
This update adds JavaScript tests to ensure the Gantt chart's side panel functions correctly, specifically when sample mode is active and when scheduling tasks. These tests verify that the side panel is hidden as expected and that the correct information is transmitted to the server.
Original PR description
In this PR, we add some tests related to changes made in this PR: https://github.com/odoo/enterprise/pull/112009 about the side panel in gantt. We test that the side panel is hidden once sample mode is enabled, and that the context of the (un)schedule action is correctly passed to the server. task-5956860
This update ensures the Enterprise version of Odoo's account reporting system is compatible with the latest OWL 3 standard. This is a crucial improvement for data accuracy and future-proofing our accounting capabilities within the Enterprise module.
Original PR description
Enterprise counter-part. https://github.com/odoo/odoo/pull/269817
This update improves the user experience by automatically notifying users via email and Odoo notifications when a document request is fulfilled. This ensures users are promptly informed about the status of their document requests, streamlining workflows and improving transparency.
Original PR description
When a document is requested from any user/partner, it is helpful to be notified when the document is uploaded. This commit does the same. The requester is notified with email/push notification when the document request is fulfilled. Some tests are also modified to verify the behaviour. Task-5446939
This update allows users to group and filter POS orders based on their DIAN transmission status, which was previously unavailable. Previously, it was difficult to identify rejected or failed orders, hindering visibility into the daily synchronization process. This change enhances reporting and provides better insights into POS order health.
Original PR description
The DIAN transmission status (l10n_co_edi_pos_dian_state) is a non-stored computed field, so it could not be used to group, filter or sort the POS Orders list: users had no way to isolate rejected or failed orders, nor to get an overview of daily sync health. Provide a compute_sql for the field so the ORM can express it in SQL, making it groupable/searchable/sortable without storing it. This avoids a schema change while keeping the value derived from the most recent DIAN document. task-6273842 Forward-Port-Of: odoo/enterprise#120929
This update removes the outdated 'reception report' feature and integrates changes from the community to improve barcode scanning and product allocation tracking. Specifically, it highlights unusual product locations and adds a button to print operation reports for allocated items, ensuring accurate inventory management.
Original PR description
*: industry_fsm_stock, stock_barcode, stock_barcode_picking_batch This commit adapts code to changes made in community: - Remove `stock.group_reception_report`; - Set `auto_show_reception_report` in picking type if needed. task-4894566 **Community PR:** odoo/odoo#264299 **Upgrade PR:** odoo/upgrade#10320
This update streamlines the loading process for Odoo's registry, resulting in a 7% performance improvement. The change removes an unnecessary check that slowed down loading times, particularly for the planning module. This translates to a quicker startup experience for the system.
Original PR description
has_group for superuser during module loading is slow and unnecessary (``@api.depends(lambda self: self._display_name_fields())``) This commit bypasses the check and improves the loading time by 7% for the registry (assume all modules are loaded in other registries) <img width="1504" height="382" alt="image" src="https://github.com/user-attachments/assets/94da0b4a-f728-4783-8883-5d7925dcb34b" />
This update streamlines the process for filing the 273S report, aligning with government regulations. It introduces a clear lifecycle for reports and proactive warnings to ensure accurate data submission, reducing potential errors and improving compliance.
Original PR description
This commit introduces a comprehensive management system for the 273S report, enhancing its lifecycle, data integrity, and user experience. It's important to note that filing a 237S report can…
This commit introduces a comprehensive management system for the 273S report, enhancing its lifecycle, data integrity, and user experience. It's important to note that filing a 237S report can involve one of the following declarations: 1. Initial declaration 2. Modification declaration 3. Cancellation declaration **After contacting the Service Public Federal (SPF) Finances, we have clarified that only Initial declarations are used in practice, and that modification and cancellation declarations are not used.** **Initial Declarations are used to modify reports that have already been declared** Ideally, a maximum of 12 Initial declarations should be used, but since modifications can also happen, a system is implemented to report the payslips of the year using the minimal amount of declared and corrected reports possible throughout the year by reporting each payslip that's not included in any ready/done report that exists in the period starting from the beginning of the year until the end of the month of the report. **Lifecycle & Structure** * 273S reports are now persistent documents with a clear lifecycle (Draft, Ready, Done, Cancelled) rather than transient pop-ups. * In the draft state, all fields are editable except Year and Month in the type `correction` since they are inherited from the original report. The original report is a required field for the correction type. Payslips are auto-populated if any of the fields (Year, Month, Original, Type) are updated. Populating a report differs based on its type; if it's an original declaration, then the report is populated by all payslips that are in a ready/done state that were issued starting from the current year and until the end of the declared month; if it's a correction report, then it's populated with payslips that aren't in a **finalised report**. **A finalised report is a report that is in a ready/done state and not one of its parent correction reports. Once the report has payslips in it, a button appears to generate the PDF (for the user) and XML (to be submitted) files.** * Once generated, the report moves to the Ready state, allowing users to review the data before final submission. In this state, all fields become non-editable except for the Reference field, which should be used to add the reference of the declaration received from the government after submission. The report can be set back to draft if any changes are needed. If a report that needs to be corrected was set to draft, it will no longer be considered in the first warning type since its `is_correction_needed` will be set to False. * Done state is the next state after Ready, which is achieved by the action `Mark as done` and requires the Reference field to be filled. Since the Reference field is important for the traceability of the declaration report, it's set to be tracked in the chatter. Done state and Ready state are alike except for the fact that Done state is for reports that are already declared to the government and have the reference of the declaration while Ready state is for reports that are generated but not yet declared to the government that's why a `Set to draft` action is allowed for Ready state and the Done state cannot be reached without filling the Reference field. The action `Correct` is shown for Done reports to allow creating a new correction report with the same period and payslips as the original report. * Cancelled state is the last state in the lifecycle and can be reached from any of the previous states. Once a report is cancelled, it cannot be set back to any other state, and all its data becomes non-editable except the Reference field. **UI & Proactive Warnings** * Two warnings are also added to the dashboard to alert the user when some reports are outdated and need to be corrected, or when some payslips are missing from the declaration of the previous year. * For the first warning, a report is considered outdated when one of its payslips has been cancelled after the report was generated. * For the second warning, a payslip is considered missing from last year's declaration when it belongs to the previous year and is not included in any ready/done report of the previous year. Missing payslips will be declared in December's Initial Declaration report of the previous year or a correction report if December's report is already declared. The warning for missing payslips of only one previous year is shown. Task: 5473528
This update enhances the accuracy of withholding tax calculations for Belgian employees. The changes incorporate more detailed criteria, such as residency status and employment duration, to ensure compliance with Belgian tax regulations and improve the precision of tax deductions.
Original PR description
In this commit, we improved the bareme computation in withholding tax, by taking into consideration more conditions (Resident, Frontalier, contract covering the full year, works in belgium for >= 75%, ..) task-6231497
This update allows administrators to directly adjust the total amounts for individual lines within payroll calculations. Previously, these totals were fixed, leading to potential discrepancies. This change improves payroll accuracy and provides greater control for financial teams.
Original PR description
Task: 6292521
This update enhances the timesheet assistant by allowing administrators to precisely control which employees receive suggestions based on new 'Applies To' settings. It also introduces a threshold feature, ensuring activity suggestions are only displayed when a specific usage level is reached, optimizing efficiency. This change improves the relevance and usability of the timesheet assistant.
Original PR description
- Replace the "Shared With" mechanism with an "Applies To" field to control which employees a rule applies to. - Add threshold support so activity suggestions are only displayed when the configured threshold is reached. task-6186073
This update enhances employee record management by adding a certificate column to employee profiles, allowing easy viewing and download. Additionally, uploaded certificates are now automatically stored in the Documents folder, streamlining the process for both new and existing certificates.
Original PR description
This PR includes some changes related to the certificates in hr_skills. First of all, we add a column in the list view found in the Certificates tab on the employee profile that shows the certificate that has been uploaded. This also allows the downloading of the certificate. Secondly, we make it so that if documents is installed, the uploaded certificates are uploaded to the Certificate folder in Documents. Task: 6210153
This update enhances the visual design of the call debrief transcription layout, making it more user-friendly. Specifically, it adds an 'active' state to the timeline markers, providing clearer visual cues for key moments during the call. This improves clarity and usability of the call debrief feature.
Original PR description
This commit refines the design of the call debrief transcription layout. It also adds an active state to the timeline markers. task-6119464 Requires: - https://github.com/odoo/odoo/pull/271103 --- |…
This commit refines the design of the call debrief transcription layout. It also adds an active state to the timeline markers. task-6119464 Requires: - https://github.com/odoo/odoo/pull/271103 --- | Header | Header | |--------|--------| | <img width="955" height="440" alt="Screenshot 2026-06-19 at 16 38 12" src="https://github.com/user-attachments/assets/114819c7-8bec-4a65-af13-9f834e692053" /> | <img width="947" height="820" alt="Screenshot 2026-06-19 at 16 39 24" src="https://github.com/user-attachments/assets/62374140-6819-4557-8181-6fd36b006cc5" /> | | <img width="960" height="247" alt="Screenshot 2026-06-19 at 16 38 28" src="https://github.com/user-attachments/assets/b25368c8-b545-4fc7-8211-907faed28926" /> | <img width="954" height="368" alt="Screenshot 2026-06-19 at 16 39 45" src="https://github.com/user-attachments/assets/1836c801-c383-43cb-aa11-ef2ec3e496cb" /> | | <img width="955" height="449" alt="Screenshot 2026-06-19 at 16 38 49" src="https://github.com/user-attachments/assets/983dd118-a3dd-4055-8af4-703217047e8b" /> | <img width="957" height="614" alt="Screenshot 2026-06-19 at 16 40 08" src="https://github.com/user-attachments/assets/5b22f3e4-9af7-4ce9-b3fd-b997964c5794" /> |
This update significantly improves Clickbot's logging capabilities by providing detailed context around errors during automated testing. Now, when a Clickbot error occurs, the logs include information about the specific application, menu, and view being used, making it much easier for developers to quickly identify and resolve issues. This reduces troubleshooting time and improves the stability of automated testing.
Original PR description
This commit enhances the Clickbot logging mechanism to make it much easier to pinpoint exactly where an error occurs during an automated run. The major improvements include: * Contextual Tracebacks: For each error, the log now prints the active application, menu, view, and filter currently being tested. * Console Interception: It intercepts all standard console errors and warnings, automatically appending this contextual application data to them. * Reduced Noise: To keep the overall log size manageable, routine click events are no longer logged unless required. task-6325836
This update enhances the timesheet grid by aligning color indicators with employee schedules. Now, the grid accurately reflects whether hours worked meet expected targets, considering different schedule types (flexible, fully flexible, and weekly totals). This ensures a clearer and more reliable view of employee time tracking.
Original PR description
Improve timesheet grid color logic to align with employee working schedules. - Fixed & flexible (with hours per day): green when hours are >= expected, red when < expected - Flexible without daily hours & fully flexible: no color on daily values - Weekly totals: green when total >= expected, red when < expected - Fully flexible schedules: no color applied task-6035150
This update enhances the stock barcode configuration process by providing a real-time preview of the scanning instructions directly within the operation type setup. This allows users to better understand and configure scanning settings in real-time, improving accuracy and efficiency. A clarification was also made regarding the 'no' scan source location setting.
Original PR description
This commit adds the instructions preview directly in the operation types' form view. The purpose is to have a preview of the scanning step in real-time while configuring the operation type. [task-5073172](https://www.odoo.com/odoo/966/tasks/5073172)
Resolved issues and error corrections
A recent payroll upgrade introduced an error preventing users from accessing the Wage Types configuration in Odoo. This change required restoring the action's update functionality to ensure the system correctly reflects the latest payroll structure settings. This fix resolves a critical issue impacting Swiss payroll functionality.
Original PR description
The Wage Types action record salary rules belonging to the CHMONTHLYELM payroll structure. During the payroll refactoring, salary rules were changed to support multiple payroll structures. in the…
The Wage Types action record salary rules belonging to the CHMONTHLYELM payroll structure.
During the payroll refactoring, salary rules were changed to support multiple payroll structures. in the 19.4 version here c2f18f3
Where struct_id M20 field is changes to [M2m](https://github.com/odoo/upgrade/pull/10294/changes#diff-541246af074f8ac598b0a274ef9861f5fe974e6ded22e906c3d35adecb284e8cR51) struct_ids
Opening Payroll > Configuration > Company > Wage Types will cause the issue as the action has not updated which Failes the [ci/upgrade_enterprise](https://runbot.odoo.com/runbot/batch/2598248/build/115031148)
Steps to reproduce.
- Create a database on saas-19.3.
- Install l10n_ch_hr_payroll.
- Upgrade the database to master.
- Open Payroll > Configuration > Company > Wage Types.
- Error raise error(message % (*args, self.field_expr, self.operator, self.value)) ValueError: Invalid field hr.salary.rule.struct_id in condition
('struct_id.code', '=', 'CHMONTHLYELM')
The issue will directly reproduce in the runbot maste too installed the l10n_ch_hr_payroll module and access the wage type.
```
Adding menu ('l10n_ch_hr_payroll.menu_l10n_ch_wage_types', 1598, 'Payroll > Configuration > Company > Wage Types', 2337) to the failing menus
Traceback (most recent call last):
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L964)", line 964, in __get_field
field = model._fields[field_name]
~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'struct_id'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L346)", line 346, in crawl_menu
self.mock_action(action_vals)
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L377)", line 377, in mock_action
return self.mock_act_window(action)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L537)", line 537, in mock_act_window
mock_method(model, view, fields_list, domain, group_by)
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L675)", line 675, in mock_view_list
return self.mock_view_tree(model, view, fields_list, domain, group_by)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L688)", line 688, in mock_view_tree
self.mock_web_search_read(model, view, [domain], fields_list)
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L722)", line 722, in mock_web_search_read
data = model.search_read(domain=domain, fields=fields_list, limit=80, order=filter_order(model))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/models.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/models.py#L5187)", line 5187, in search_read
records = self.search_fetch(domain or [], fields, offset=offset, limit=limit, order=order)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/models.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/models.py#L1462)", line 1462, in search_fetch
query = self._search(domain, offset=offset, limit=limit, order=order or self._order)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/models.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/models.py#L4773)", line 4773, in _search
domain = domain.optimize_full(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L472)", line 472, in optimize_full
return self._optimize(model, OptimizationLevel.FULL)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L486)", line 486, in _optimize
previous, domain = domain, domain._optimize_step(model, next_level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L670)", line 670, in _optimize_step
children = self._flatten(child._optimize(model, level) for child in self.children)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L628)", line 628, in _flatten
for child in children:
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L670)", line 670, in <genexpr>
children = self._flatten(child._optimize(model, level) for child in self.children)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L486)", line 486, in _optimize
previous, domain = domain, domain._optimize_step(model, next_level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L988)", line 988, in _optimize_step
field, property_name = self.__get_field(model)
^^^^^^^^^^^^^^^^^^^^^^^
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L966)", line 966, in __get_field
self._raise("Invalid field %s.%s", model._name, field_name)
File "[/data/build/odoo/odoo/orm/domains.py](https://github.com/odoo/odoo/blob/2fb276668c824d6fe759a7c51f9ef10677532508/odoo/orm/domains.py#L951)", line 951, in _raise
raise error(message % (*args, self.field_expr, self.operator, self.value))
ValueError: Invalid field hr.salary.rule.struct_id in condition ('struct_id.code', '=', 'CHMONTHLYELM')
2026-06-22 12:02:29 [ERROR](https://github.com/odoo/upgrade-util/blob/f3431df77099e3df9299b9d6fb1ea001796c176c/src/testing.py#L483)
FAIL: TestCrawler.test_check
Traceback (most recent call last):
File "[/data/build/upgrade-util/src/testing.py](https://github.com/odoo/upgrade-util/blob/f3431df77099e3df9299b9d6fb1ea001796c176c/src/testing.py#L483)", line 483, in test_check
self.check(value)
File "[/data/build/upgrade/migrations/base/tests/test_mock_crawl.py](https://github.com/odoo/upgrade/blob/07bec6a1031093cf001642f8df21e40421cce3be/migrations/base/tests/test_mock_crawl.py#L230)", line 230, in check
self.assertFalse(diff, msg)
AssertionError: [('l10n_ch_hr_payroll.menu_l10n_ch_wage_types', 1598, 'Payroll > Configuration > Company > Wage Types', 2337)] is not false : At least one menu or view working before upgrade is not working after upgrade.
```
Soln:- Update the action with the correct field.
ref :- https://runbot.odoo.com/runbot/batch/2598248/build/115031148This update fixes a bug where rental order PDFs didn't show the pickup and return dates. The fix adds the necessary date fields to the PDF report, ensuring consistent information between the portal and the printed sales orders. This improves clarity for customers receiving rental order details.
Original PR description
**Problem:** On a rental order, the sales order / quotation PDF no longer shows the pickup and return dates. The line description only displays the rental duration (e.g. "2 Days"), so the actual…
**Problem:** On a rental order, the sales order / quotation PDF no longer shows the pickup and return dates. The line description only displays the rental duration (e.g. "2 Days"), so the actual dates are missing from the printout. **Steps to reproduce:** 1. Create a rental order with a rentable product and pickup/return dates 2. Print the order (Print > Quotation / Order) 3. Observe the PDF shows only the duration, with no pickup/return dates **Current behavior:** Neither the rental dates (removed from the description) nor any pickup/return field appear on the PDF. **Expected behavior:** The pickup and return dates are shown on the rental order PDF. **Cause of the issue:** The rental line description was intentionally reduced to only the duration (`_get_rental_duration_description`), the actual dates being meant to appear as dedicated Pickup/Return fields. This was added to the customer portal (`sale_rental_portal_details` inherits `sale.sale_order_portal_content`) but the equivalent was never added to the `sale.report_saleorder_document` PDF report, so the dates disappeared from the printout. **Fix:** Inherit the sale order report to render the order-level pickup and return dates for rental orders, mirroring the existing portal presentation so the PDF and the portal stay consistent. opw-6268640 Forward-Port-Of: odoo/enterprise#119736
A bug preventing users from adding cover images to Knowledge articles has been resolved. The issue stemmed from a missing callback function during the upload process, causing the upload to fail. This update ensures cover images can now be successfully added, improving the article creation workflow.
Original PR description
Steps to reproduce: 1. Install Knowledge. 2. Create an article. 3. Open the more actions menu. 4. Click "Add Cover". 5. Upload a cover image. Issue: - The upload crashes with the following traceback:…
Steps to reproduce: 1. Install Knowledge. 2. Create an article. 3. Open the more actions menu. 4. Click "Add Cover". 5. Upload a cover image. Issue: - The upload crashes with the following traceback: `Uncaught Promise > this.props.setAbortUploadsCallback is not a function` Cause: - `KnowledgeCoverSelector` extends the html_editor `ImageSelector`, whose upload flow registers an abort callback through setAbortUploadsCallback. The generic MediaDialog provides this callback, but KnowledgeCoverDialog renders KnowledgeCoverSelector directly and did not pass it. As a result, the inherited upload flow called a missing prop. Solution: - Pass setAbortUploadsCallback from KnowledgeCoverDialog to KnowledgeCoverSelector and abort pending uploads when the cover dialog is discarded. Alternative approach: - Make ImageSelector tolerate callers that do not provide setAbortUploadsCallback by calling it with optional chaining. opw-6176716 Forward-Port-Of: odoo/enterprise#121162 Forward-Port-Of: odoo/enterprise#116906
This update fixes an issue preventing users from accessing payslip lists within the employee departure process. The changes include making fields read-only to prevent unintended modifications and relocating currency data to improve data handling. This ensures accurate payslip access and avoids errors.
Original PR description
Bug 1: In the departure tab of the Employee, you can't open the payslip list Fix: Added a check to get the correct departure id depending on the model we are in Bug 2: You can select payslips for other employees than the departing employee and the payslips list is not affected Fix: made fields `l10n_be_payslip_n_ids` and `l10n_be_payslip_n1_ids` readonly so they can't be modified in the UI without being saved Bug 3: You get an error because you can't read `currency_id` when opening n payslips (happens when the monetary fields are shown in the list) Fix: moved the `currency_id` to be inside the list instead of the parent form task-id: 6265648 Forward-Port-Of: odoo/enterprise#119402
This update resolves an issue preventing the 'Send to SII' option from appearing on Chilean vendor bills. The fix adjusts internal settings to correctly display this functionality, ensuring accurate electronic invoice submission for Chilean businesses. This ensures compliance with local tax regulations.
Original PR description
**Steps to reproduce:** * Install the **l10n_cl_edi** module. * Go to **Accounting → Configuration → CAFs**, create a new CAF, and upload a valid CAF…
**Steps to reproduce:** * Install the **l10n_cl_edi** module. * Go to **Accounting → Configuration → CAFs**, create a new CAF, and upload a valid CAF [XML](https://www.odoo.com/mail/message/1097235975) file. * Create a new **Purchase Journal** with **Use Documents** enabled. * Create a vendor bill using this journal. * Set the **Document Type** to **46 - Liquidación-Factura Electrónica**. * Confirm the vendor bill. **Observed behavior:** * The Send button is not visible on the confirmed vendor bill despite the DTE being generated and `l10n_cl_dte_status` being set to `not_sent`. **Cause:** * `_compute_display_send_button` in `account` only returns `True` for sale documents (`is_sale_document()`), so the "Send" button — which opens the Send & Print dialog containing the "Send to SII" option — was never shown on vendor bills. * `_get_move_constraints` in `account.move.send` unconditionally adds a `not_sale_document` constraint for non-sale documents, blocking the Send & Print dialog from processing vendor bills even if the button were visible. * The cron's `cron_run_sii_workflow` only processes moves with `l10n_cl_dte_status = 'ask_for_status'`, skipping moves still in `not_sent` state. **Fix:** * Override `_compute_display_send_button` in `l10n_cl_edi` to also show the "Send" button on posted moves with `l10n_cl_dte_status == 'not_sent'`, matching the pattern used by `l10n_br_edi`. * Override `_get_move_constraints` in `l10n_cl_edi` to remove the `not_sale_document` constraint for Chilean purchase documents with `not_sent` status, matching the pattern used by `l10n_br_edi`. **REF** During this [refactor](https://github.com/odoo/enterprise/pull/103427/changes/f5617ecf7584cf019897408df94b002622f48d9d), these two methods were inadvertently missed and were not overridden opw-6300571 Forward-Port-Of: odoo/enterprise#121233 Forward-Port-Of: odoo/enterprise#120818
This update significantly speeds up how Odoo retrieves document access permissions, particularly for the 'my counters' route. By switching to a subquery, the system now utilizes an index more efficiently, resulting in a much faster response time for users accessing documents. This improves overall performance and user experience.
Original PR description
The '/my/counters' route is hit a lot of times on big databases like odoo.com One thing it does is a `self.env['documents.document].search_count([])` With this commit, we use a subquery for the…
The '/my/counters' route is hit a lot of times on big databases like odoo.com
One thing it does is a `self.env['documents.document].search_count([])`
With this commit, we use a subquery for the folder access instead of the current LEFT JOIN.
This ok since the number of folders is typically small compared to regular documents and the query is fast since it can use the index on 'type'
Before as portal user
------
2x Seq Scan
```
Aggregate (cost=1900290.73..1900290.74 rows=1 width=8) (actual time=282.271..282.276 rows=1 loops=1)
Buffers: shared hit=66629
-> Hash Left Join (cost=41649.94..1900044.55 rows=98472 width=0) (actual time=184.202..282.267 rows=3 loops=1)
Hash Cond: (documents_document.folder_id = documents_document__folder_id.id)
Filter: ((hashed SubPlan 2) OR ((documents_document.owner_id = 6) AND ((documents_document.shortcut_document_id IS NULL) OR (documents_document.shortcut_document_owner_id = 6))) OR (((documents_document.access_via_link)::text = ANY ('{edit,view}'::text[])) AND (documents_document.folder_id IS NOT NULL) AND ((hashed SubPlan 4) OR ((documents_document__folder_id.owner_id = 6) AND ((documents_document__folder_id.shortcut_document_id IS NULL) OR (documents_document__folder_id.shortcut_document_owner_id = 6)))) AND (documents_document.is_access_via_link_hidden IS NOT TRUE)))
Rows Removed by Filter: 28085
Buffers: shared hit=66629
-> Seq Scan on documents_document (cost=0.00..1857903.54 rows=187073 width=26) (actual time=0.022..109.288 rows=28088 loops=1)
Filter: ((active IS TRUE) AND ((hashed SubPlan 2) OR ((owner_id = 6) AND ((shortcut_document_id IS NULL) OR (shortcut_document_owner_id = 6))) OR (((access_via_link)::text = ANY ('{edit,view}'::text[])) AND (folder_id IS NOT NULL) AND (is_access_via_link_hidden IS NOT TRUE))))
Rows Removed by Filter: 342576
Buffers: shared hit=33313
SubPlan 2
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.008..0.009 rows=0 loops=2)
Buffers: shared hit=6
-> Index Scan using documents_access__partner_id_index on documents_access (cost=0.43..105.55 rows=103 width=9) (actual time=0.008..0.008 rows=0 loops=2)
Index Cond: (partner_id = 7)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 10:16:38'::timestamp without time zone))
Buffers: shared hit=6
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id (cost=0.42..2.44 rows=1 width=9) (never executed)
Index Cond: (id = documents_access.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access.role)::text = ANY ('{view,edit}'::text[])))
-> Hash (cost=37016.64..37016.64 rows=370664 width=16) (actual time=164.521..164.521 rows=370664 loops=1)
Buckets: 524288 Batches: 1 Memory Usage: 17824kB
Buffers: shared hit=33310
-> Seq Scan on documents_document documents_document__folder_id (cost=0.00..37016.64 rows=370664 width=16) (actual time=0.005..100.491 rows=370664 loops=1)
Buffers: shared hit=33310
SubPlan 4
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.003..0.003 rows=0 loops=1)
Buffers: shared hit=3
-> Index Scan using documents_access__partner_id_index on documents_access documents_access_1 (cost=0.43..105.55 rows=103 width=9) (actual time=0.002..0.003 rows=0 loops=1)
Index Cond: (partner_id = 7)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 10:16:38'::timestamp without time zone))
Buffers: shared hit=3
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id_1 (cost=0.42..2.44 rows=1 width=9) (never executed)
Index Cond: (id = documents_access_1.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access_1.role)::text = ANY ('{view,edit}'::text[])))
Planning:
Buffers: shared hit=69
Planning Time: 1.708 ms
Execution Time: 282.344 ms
```
After as portal user
-----
Only 1x Seq Scan
```
Aggregate (cost=2004948.33..2004948.34 rows=1 width=8) (actual time=116.161..116.165 rows=1 loops=1)
Buffers: shared hit=37942
-> Seq Scan on documents_document (cost=145660.16..2004490.36 rows=183187 width=0) (actual time=24.635..116.155 rows=3 loops=1)
Filter: ((active IS TRUE) AND ((hashed SubPlan 2) OR ((owner_id = 6) AND ((shortcut_document_id IS NULL) OR (shortcut_document_owner_id = 6))) OR (((access_via_link)::text = ANY ('{edit,view}'::text[])) AND (hashed SubPlan 5) AND (is_access_via_link_hidden IS NOT TRUE))))
Rows Removed by Filter: 370661
Buffers: shared hit=37942
SubPlan 2
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.008..0.009 rows=0 loops=1)
Buffers: shared hit=3
-> Index Scan using documents_access__partner_id_index on documents_access (cost=0.43..105.55 rows=103 width=9) (actual time=0.008..0.008 rows=0 loops=1)
Index Cond: (partner_id = 7)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 10:15:10'::timestamp without time zone))
Buffers: shared hit=3
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id (cost=0.42..2.44 rows=1 width=9) (never executed)
Index Cond: (id = documents_access.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access.role)::text = ANY ('{view,edit}'::text[])))
SubPlan 5
-> Index Scan using documents_document__type_index on documents_document documents_document_1 (cost=0.42..145625.73 rows=13772 width=4) (actual time=11.688..11.689 rows=0 loops=1)
Index Cond: ((type)::text = 'folder'::text)
Filter: ((hashed SubPlan 4) OR ((owner_id = 6) AND ((shortcut_document_id IS NULL) OR (shortcut_document_owner_id = 6))))
Rows Removed by Filter: 28198
Buffers: shared hit=4629
SubPlan 4
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.002..0.002 rows=0 loops=1)
Buffers: shared hit=3
-> Index Scan using documents_access__partner_id_index on documents_access documents_access_1 (cost=0.43..105.55 rows=103 width=9) (actual time=0.001..0.002 rows=0 loops=1)
Index Cond: (partner_id = 7)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 10:15:10'::timestamp without time zone))
Buffers: shared hit=3
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id_1 (cost=0.42..2.44 rows=1 width=9) (never executed)
Index Cond: (id = documents_access_1.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access_1.role)::text = ANY ('{view,edit}'::text[])))
Planning:
Buffers: shared hit=56
Planning Time: 1.544 ms
Execution Time: 116.216 ms
```
Before as internal user
--------
```
Aggregate (cost=1902165.43..1902165.44 rows=1 width=8) (actual time=332.919..332.925 rows=1 loops=1)
Buffers: shared hit=69223 read=370
-> Hash Left Join (cost=41649.94..1901908.04 rows=102955 width=0) (actual time=176.179..332.325 rows=10040 loops=1)
Hash Cond: (documents_document.folder_id = documents_document__folder_id.id)
Filter: ((hashed SubPlan 2) OR ((documents_document.owner_id = 1054906) AND ((documents_document.shortcut_document_id IS NULL) OR (documents_document.shortcut_document_owner_id = 1054906))) OR (((documents_document.access_internal)::text = ANY ('{view,edit}'::text[])) AND ((documents_document.company_id = 1) OR (documents_document.company_id IS NULL))) OR (((documents_document.access_via_link)::text = ANY ('{view,edit}'::text[])) AND (documents_document.folder_id IS NOT NULL) AND ((hashed SubPlan 4) OR ((documents_document__folder_id.owner_id = 1054906) AND ((documents_document__folder_id.shortcut_document_id IS NULL) OR (documents_document__folder_id.shortcut_document_owner_id = 1054906))) OR (((documents_document__folder_id.access_internal)::text = ANY ('{view,edit}'::text[])) AND ((documents_document__folder_id.company_id = 1) OR (documents_document__folder_id.company_id IS NULL)))) AND (documents_document.is_access_via_link_hidden IS NOT TRUE)))
Rows Removed by Filter: 27228
Buffers: shared hit=69223 read=370
-> Seq Scan on documents_document (cost=0.00..1859756.86 rows=190950 width=35) (actual time=15.029..155.718 rows=37268 loops=1)
Filter: ((active IS TRUE) AND ((hashed SubPlan 2) OR ((owner_id = 1054906) AND ((shortcut_document_id IS NULL) OR (shortcut_document_owner_id = 1054906))) OR (((access_internal)::text = ANY ('{view,edit}'::text[])) AND ((company_id = 1) OR (company_id IS NULL))) OR (((access_via_link)::text = ANY ('{view,edit}'::text[])) AND (folder_id IS NOT NULL) AND (is_access_via_link_hidden IS NOT TRUE))))
Rows Removed by Filter: 333396
Buffers: shared hit=33931 read=370
SubPlan 2
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.155..7.920 rows=148 loops=2)
Buffers: shared hit=1612 read=370
-> Index Scan using documents_access__partner_id_index on documents_access (cost=0.43..105.55 rows=103 width=9) (actual time=0.110..3.448 rows=200 loops=2)
Index Cond: (partner_id = 1800102)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 12:17:29'::timestamp without time zone))
Buffers: shared hit=192 read=190
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id (cost=0.42..2.44 rows=1 width=9) (actual time=0.022..0.022 rows=1 loops=400)
Index Cond: (id = documents_access.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access.role)::text = ANY ('{view,edit}'::text[])))
Rows Removed by Filter: 0
Buffers: shared hit=1420 read=180
-> Hash (cost=37016.64..37016.64 rows=370664 width=25) (actual time=157.822..157.823 rows=370664 loops=1)
Buckets: 524288 Batches: 1 Memory Usage: 21336kB
Buffers: shared hit=33310
-> Seq Scan on documents_document documents_document__folder_id (cost=0.00..37016.64 rows=370664 width=25) (actual time=0.005..96.730 rows=370664 loops=1)
Buffers: shared hit=33310
SubPlan 4
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.019..0.372 rows=148 loops=1)
Buffers: shared hit=991
-> Index Scan using documents_access__partner_id_index on documents_access documents_access_1 (cost=0.43..105.55 rows=103 width=9) (actual time=0.005..0.078 rows=200 loops=1)
Index Cond: (partner_id = 1800102)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 12:17:29'::timestamp without time zone))
Buffers: shared hit=191
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id_1 (cost=0.42..2.44 rows=1 width=9) (actual time=0.001..0.001 rows=1 loops=200)
Index Cond: (id = documents_access_1.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access_1.role)::text = ANY ('{view,edit}'::text[])))
Rows Removed by Filter: 0
Buffers: shared hit=800
Planning:
Buffers: shared hit=69 read=8
Planning Time: 2.116 ms
Execution Time: 333.013 ms
```
After as internal user
--------
```
Aggregate (cost=2006950.17..2006950.18 rows=1 width=8) (actual time=157.117..157.121 rows=1 loops=1)
Buffers: shared hit=39918
-> Seq Scan on documents_document (cost=145798.74..2006482.26 rows=187165 width=0) (actual time=16.595..156.590 rows=10040 loops=1)
Filter: ((active IS TRUE) AND ((hashed SubPlan 2) OR ((owner_id = 1054906) AND ((shortcut_document_id IS NULL) OR (shortcut_document_owner_id = 1054906))) OR (((access_internal)::text = ANY ('{view,edit}'::text[])) AND ((company_id = 1) OR (company_id IS NULL))) OR (((access_via_link)::text = ANY ('{view,edit}'::text[])) AND (hashed SubPlan 5) AND (is_access_via_link_hidden IS NOT TRUE))))
Rows Removed by Filter: 360624
Buffers: shared hit=39918
SubPlan 2
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.019..1.016 rows=148 loops=1)
Buffers: shared hit=991
-> Index Scan using documents_access__partner_id_index on documents_access (cost=0.43..105.55 rows=103 width=9) (actual time=0.012..0.262 rows=200 loops=1)
Index Cond: (partner_id = 1800102)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 12:16:29'::timestamp without time zone))
Buffers: shared hit=191
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id (cost=0.42..2.44 rows=1 width=9) (actual time=0.004..0.004 rows=1 loops=200)
Index Cond: (id = documents_access.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access.role)::text = ANY ('{view,edit}'::text[])))
Rows Removed by Filter: 0
Buffers: shared hit=800
SubPlan 5
-> Index Scan using documents_document__type_index on documents_document documents_document_1 (cost=0.42..145763.43 rows=14124 width=4) (actual time=0.429..14.916 rows=4625 loops=1)
Index Cond: ((type)::text = 'folder'::text)
Filter: ((hashed SubPlan 4) OR ((owner_id = 1054906) AND ((shortcut_document_id IS NULL) OR (shortcut_document_owner_id = 1054906))) OR (((access_internal)::text = ANY ('{view,edit}'::text[])) AND ((company_id = 1) OR (company_id IS NULL))))
Rows Removed by Filter: 23573
Buffers: shared hit=5617
SubPlan 4
-> Nested Loop (cost=0.85..357.41 rows=99 width=4) (actual time=0.007..0.390 rows=148 loops=1)
Buffers: shared hit=991
-> Index Scan using documents_access__partner_id_index on documents_access documents_access_1 (cost=0.43..105.55 rows=103 width=9) (actual time=0.003..0.074 rows=200 loops=1)
Index Cond: (partner_id = 1800102)
Filter: ((expiration_date IS NULL) OR (expiration_date >= '2026-06-18 12:16:29'::timestamp without time zone))
Buffers: shared hit=191
-> Index Scan using documents_document_pkey on documents_document documents_access__document_id_1 (cost=0.42..2.44 rows=1 width=9) (actual time=0.001..0.001 rows=1 loops=200)
Index Cond: (id = documents_access_1.document_id)
Filter: (((access_via_link)::text <> 'none'::text) OR ((documents_access_1.role)::text = ANY ('{view,edit}'::text[])))
Rows Removed by Filter: 0
Buffers: shared hit=800
Planning:
Buffers: shared hit=56
Planning Time: 1.569 ms
Execution Time: 157.171 ms
```
portal user
before https://explain.dalibo.com/plan/e1e755fg7bb26a21
after https://explain.dalibo.com/plan/hb5fa1d201ff164g
internal user with few documents access
before https://explain.dalibo.com/plan/f753bf2aa244dg63
after https://explain.dalibo.com/plan/538dg5ecb120ch84
internal user with *lots* of documents access
before https://explain.dalibo.com/plan/cf76h84537f7ge4a
after https://explain.dalibo.com/plan/45317a5e3168c5bc
Forward-Port-Of: odoo/enterprise#120991This update resolves an issue impacting how Odoo calculates sick leave payments, specifically related to the 'DPV' (days of paid vacation) calculation for employees with extended absences. The fix ensures accurate assimilation of sickness periods, particularly when transitioning between long and partial absences, improving payroll accuracy and compliance. The changes primarily affect the Be payroll module.
Original PR description
Forward-Port-Of: odoo/enterprise#121086 Forward-Port-Of: odoo/enterprise#120868
This update resolves a critical issue where VoIP registration would fail due to idle sessions, causing error dialogs and preventing users from making calls. The fix ensures that registration requests are properly handled and retried, preventing indefinite waiting and ensuring reliable VoIP connectivity.
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.
Forward-Port-Of: odoo/enterprise#120487
Forward-Port-Of: odoo/enterprise#119701This update resolves an issue where changing multiple project names didn't update the associated folder names. The fix ensures that when users edit project names, the linked folder names are automatically updated, streamlining project management. This prevents inconsistencies and ensures data accuracy.
Original PR description
Currently, an error will occur when user multi edits name of projects. Steps to replicate: - Install `documents_project` and open any project's settings using kebab menu (3 dots). - Click new > name…
Currently, an error will occur when user multi edits name of projects. Steps to replicate: - Install `documents_project` and open any project's settings using kebab menu (3 dots). - Click new > name `Test` > open settings page and unselect `Documents` > Save. - Click new > name `Test1` > Save. - From the list view select `Test` and `Test1` and edit their name. Error: ``` ValueError: Expected singleton: project.project(9, 10) ``` Cause: - During `multi-edit`, self contains multiple project records. - When only one of the selected projects has a documents folder (i.e. `use_documents` enabled), `self.documents_folder_id` contains that single folder, making `len(self.documents_folder_id.project_ids) == 1` to be True [1]. - The condition then proceeds to access `self.name` on the `multi-recordset`, raising singleton. Solution: - Avoided accessing `self.name` on a `multi-recordset` during multi-edit. - Filtered projects individually and updated the document folders using the name in vals. [1]: https://github.com/odoo/enterprise/blob/3c2985ca6011700c271ed14e40e08c89be822753/documents_project/models/project_project.py#L101 sentry-7452096418 Forward-Port-Of: odoo/enterprise#120654 Forward-Port-Of: odoo/enterprise#119060
This update resolves an issue where manually added by-products on manufacturing orders caused errors when closing production in the shopfloor view. The fix ensures that serial numbers are correctly handled for by-products created outside of the standard BOM definition, preventing user errors and improving production workflow.
Original PR description
**Issue** Adding a serial-tracked by-product manually on a Manufacturing Order whose BOM does not define it, can lead to inconsistencies when assigning serial numbers in the shopfloor application.…
**Issue** Adding a serial-tracked by-product manually on a Manufacturing Order whose BOM does not define it, can lead to inconsistencies when assigning serial numbers in the shopfloor application. **Steps to reproduce** - Activate by-product in the settings - Create a product with an empty BOM (final product) - Create another product tracked by serial number (by-product) - Create and confirm a MO for the final product with 1 unit of the by-product - Go to Miscellaneaous -> operation Type -> shopfloor - Activate the option "Pre fill lot/serial numbers in shop floor" - Return to the MO and open the shopfloor view - Click on the '+' button next to the by-product and assign a serial number - Try to close the production -> A user error is raised stating that the by-product requires a serial number. **Cause** When the by-product is added manually on the MO, a stock move is created with an initial move line that does not contain any serial number. Later, when assigning a serial number from the shopfloor view: https://github.com/odoo/enterprise/blob/8030b105d3fce1eef9b8965a2bfc37195f71723c/mrp_workorder/models/stock_move.py#L121-L122 a new move line containing the serial number is created: https://github.com/odoo/enterprise/blob/8030b105d3fce1eef9b8965a2bfc37195f71723c/mrp_workorder/models/stock_move.py#L116-L119 However, the original empty move line is not removed (the issue): https://github.com/odoo/enterprise/blob/8030b105d3fce1eef9b8965a2bfc37195f71723c/mrp_workorder/models/stock_move.py#L124-L125 Because `self.picking_type_prefill_shop_floor_lots` is True, but `self.byproduct_id` is an empty recordset since: https://github.com/odoo/odoo/blob/8d14665af5acf1bd391d05a5048dc701986e8b15/addons/mrp/models/mrp_production.py#L1304-L1311 https://github.com/odoo/odoo/blob/8d14665af5acf1bd391d05a5048dc701986e8b15/addons/mrp/models/mrp_production.py#L1279 Indeed, `byproduct_id` is only populated from BOM-defined by-products. As a result, while confirming the production, there is 2 sml and among them, the original one without SN, which triggers the error: https://github.com/odoo/odoo/blob/8d14665af5acf1bd391d05a5048dc701986e8b15/addons/stock/models/stock_move_line.py#L590 https://github.com/odoo/odoo/blob/8d14665af5acf1bd391d05a5048dc701986e8b15/addons/stock/models/stock_move_line.py#L634-L635 https://github.com/odoo/odoo/blob/8d14665af5acf1bd391d05a5048dc701986e8b15/addons/stock/models/stock_move_line.py#L658-L659 https://github.com/odoo/odoo/blob/8d14665af5acf1bd391d05a5048dc701986e8b15/addons/stock/models/stock_move_line.py#L661-L669 opw-6223158 Forward-Port-Of: odoo/enterprise#120493 Forward-Port-Of: odoo/enterprise#118792
This update resolves an issue where the system wasn't properly validating partner banks when creating SEPA direct debit mandates. The change adds a constraint to ensure the correct bank is associated with each mandate, improving data accuracy and preventing potential errors in payment processing. This enhances the reliability of our SEPA direct debit functionality.
Original PR description
Forward-Port-Of: odoo/enterprise#121236 Forward-Port-Of: odoo/enterprise#120901
This update resolves a warning in the Odoo payroll system that was causing incorrect results or access errors. The fix corrected a misconfiguration that was incorrectly targeting employee data instead of the version model. This ensures accurate payroll calculations and reliable system performance.
Original PR description
The warning `hr_payroll_warning_wrong_work_code` was targetting the version model but was returning employee records which led to the wonrg result or access errors
This update cleans up the appearance of payslips by removing unnecessary trailing zeros from the line rate displayed in the salary section. This improves the clarity and professionalism of payroll reports for employees and managers. It's a small but important visual enhancement.
Original PR description
Problem: A lot of trailing zeros were displayed on the rate of each payslip line, in the salary tab of the payslip form. Solution: We simply hid trailing zeros. Task-6310227
This update resolves a bug where tests were failing due to outdated configurations after removing a field. The tests have been updated to correctly utilize the new 'is_live' field, ensuring accurate functionality for rental stock processes. This ensures the system continues to operate reliably.
Original PR description
Some tests were not adapted after removing state field, this caused the failed tests, the tests are now adatped to set up the is_live field instead. Community: https://github.com/odoo/odoo/pull/271052
This update fixes a technical issue in the Belgian payroll localization (l10n_be_hr_payroll) where a field was incorrectly configured to accept monetary values instead of the intended quantity. This change ensures accurate calculation of 'Forced # Months' compensation rules, aligning with Belgian accounting standards.
Original PR description
In Belgium localization salary rule "Forced # Months", the input unit type was monetary when it supposed to be quantity. This commit changes the input type to the correct one (quantity) Task: 6241599
This update fixes a potential issue where changes to the Point of Sale system could disrupt the display of receipt quantities. By using a more flexible method to locate the relevant data, the update ensures the receipt information remains accurate and consistent, regardless of future Point of Sale updates. This enhances the reliability of the receipt generation process.
Original PR description
In this commit - -------------- Use a more generic xpath on the receipt quantity span instead of matching the full class attribute, so the template inheritance does not break when point_of_sale updates the text size class.
This update corrects a previous issue where Odoo was incorrectly selecting unavailable couriers from Shiprocket. The fix now filters out ‘blocked’ couriers, ensuring only serviceable options are considered for rate calculations and shipment selection. Additionally, the system is now more robust in handling potential errors from Shiprocket’s data.
Original PR description
Shiprocket provides an odablock flag in the courier serviceability response. Couriers with odablock=True are not serviceable for the requested route and should not be considered for rate calculation or selection. Before this change, Odoo selected the first courier returned by Shiprocket regardless of its ODA status. As a result, unavailable couriers could be proposed to users and selected for shipments. The fix filters out ODA-blocked couriers before evaluating available services, ensuring that only serviceable couriers are considered. Additionally, freight charge parsing is hardened to gracefully handle non-numeric values returned by Shiprocket, preventing errors during AWB assignment and price computation. FYI: Shiprocket uses odablock=False for serviceable routes and odablock=True for routes that are blocked for a given courier. opw-6288768,6152279 Forward-Port-Of: odoo/enterprise#120374
This update optimizes how the system searches for documents, specifically addressing a slow and complex query when filtering by 'not SHARED'. The change aligns with the production database's approach, resulting in faster and more efficient searches. This improves overall user experience and system responsiveness.
Original PR description
Searching for "not 'SHARED'" results in a very complex query. Our own production DB prefers this implementation, also easier to read. credit: https://github.com/odoo/enterprise/pull/105915#discussion_r2745148099 Task-5893183 Forward-Port-Of: odoo/enterprise#121070 Forward-Port-Of: odoo/enterprise#120870
This update fixes a bug where changes to employee data didn't correctly update past payslips. The fix ensures that all affected payslips are accurately corrected when a user manages them, preventing discrepancies in payroll calculations. This improves data accuracy and payroll processing reliability.
Original PR description
Steps to reproduce: 1. Make sure you have an employee with a contract 2. Create 2 payslips for this employee 3. Change any field of the employee (ex: job position) 4. Go to one of the payslips…
Steps to reproduce: 1. Make sure you have an employee with a contract 2. Create 2 payslips for this employee 3. Change any field of the employee (ex: job position) 4. Go to one of the payslips created before 5. Click on the "Manage Payslips" link appearing because of the change of data Problem: When the data of an employee has been modified and past payslip are affected, the popup currently states 0 payslip has been affected. When clicking the "Correct" button, the correct amount briefly shows before we are sent to the payslip page where only one payslip gets corrected. Source of the problem: - The `employee_id` field was missing from the wizard form view. Since it was not referenced anywhere in the view, the web client did not include it in the initial payload / default_get calls. As a result, the wizard was initialized without `employee_id`, causing the payslip computation to use an empty employee and return a count of 0. - The window action did not explicitly call the intended wizard form view. Odoo therefore selected an unintended inherited view (salary increase wizard) due to view resolution rules (inheritance and priority ordering). This inherited view specifically replaces the description and the correction choice with nothing, which explains why it didn't show before. Fix: - Add an invisible `employee_id` field in the form view to ensure it is included in the initial form payload and properly initialized from context defaults. - Explicitly specify the correct view in the `views` parameter of the window action to prevent fallback to an inherited or unintended view. - Add an explicit priority on the salary increase wizard view to avoid ambiguous view selection in the future. Task-6304311
This update resolves an issue where the 281.XX report generation failed due to missing employee first and last names. The fix adds a check to ensure these fields are populated, preventing errors and ensuring accurate report creation. This improves the reliability of payroll reporting.
Original PR description
Steps to reproduce: 1. Create a Belgian company with a full address, phone and VAT 2. Create an employee of this company with a full private address, valid NISS (or "/"), and give him a contract. 3. Make sure the employee doesn't have a first name or a last name set. 4. Create some payslips for the employee (one is enough). 5. Go to Reporting > 281.XX Sheets and try creating a new report for the corresponding year. Problem: When pressing "Compute", you will see a traceback indicating us that an error occured because of the first name not being set. Fix: Adding a check to make sure that the first and last name are set, and raising an error if it is not the case. Task-6318024
This update resolves a crash that occurred when users viewed real Instagram videos within Odoo. The fix now displays the video link instead of attempting to show the video as an image, preventing the previewer from failing. This ensures a smoother user experience when viewing Instagram content.
Original PR description
Purpose ======= When we have a real on Instagram, we try to show the video as an image. When clicking on the broken image, the previewer crash. To fix that issue, we know show the link of the video in the message. Task-5491124 Forward-Port-Of: odoo/enterprise#121176 Forward-Port-Of: odoo/enterprise#113487
This update strengthens the testing process for the AI call debrief feature in Odoo Enterprise. Previously, the test relied on a quick trigger, which wasn't reliable due to the time it takes for browsers to complete audio seeking. This fix adds a deliberate wait, ensuring the test accurately reflects real-world scenarios and improves the overall stability of the AI call debrief functionality.
Original PR description
Before (in the test), we trigger the media loading by manually dispatching the loadeddata event. Once loadeddata runs, our component updates the <audio> element with the new time and triggers the seek. But because the actual seek in the browser takes time, we cannot just do a simple animationFrame(). We must explicitly wait for the browser to finish seeking and that's what we do in this fix. task-6321435 **community counter-part** https://github.com/odoo/odoo/pull/271300
This update corrects a bug where RCM entries for service imports were missing from the GSTR2B report. The team added a necessary section to the report's domain, ensuring accurate reporting of import service charges as required by Indonesian tax regulations. This ensures compliance and accurate financial reporting.
Original PR description
In commit https://github.com/odoo/odoo/commit/16c0ef65b3b755ddb8256914d8f16ecf48e36409, a new section purchase_imp_services_rcm was introduced, but it was not added to the GSTR2B domain. As a result, RCM entries for import of services were missing from the GSTR2B report. This commit adds the new section to the GSTR2B report line domain.
This update resolves an issue where opening attendance records from the Gantt view was failing. The fix removes a redundant process that caused a system deadlock, ensuring that attendance records can now be opened as expected. This improves the usability of the attendance tracking feature.
Original PR description
Steps To Reproduce: Try to open any existing attendance record from gantt view. It doesn't open the Dialog. Issue: onPillClicked wraps `openDialog` in mutex.exec(), but openDialog() already calls mutex.exec() internally, causing a deadlock — the inner exec waits for the outer to finish, while the outer awaits the inner. Fix: Remove redundant mutex.exec() wrapper in onPillClicked. task-6317228
This update prevents users who aren't designated approvers from directly accepting or rejecting approval requests through the system's activity interface. Previously, this allowed unintended actions, creating a potential security risk. This change ensures that approval workflows remain controlled and secure.
Original PR description
Currently when a user submits an approval request, an activity is created for the approver who can validate or refuse the request directly from the activity, however these options are also visible to other users who will trigger an error if interacting with the options. This commit removes these options for users who are not the approver. **Steps to reproduce:** - Log in as admin - Go to approvals - Select dropdown menu of General Approval and Edit - Change documents to optionnal - Make sure admin is in the approvers list - Log in as demo - Go to approvals -> General Approval -> New Request - Submit the request - You'll see an activity be created for admin, with Accept and Refuse options - If you select any of these options you will get an access error opw-5423528 Forward-Port-Of: odoo/enterprise#120767 Forward-Port-Of: odoo/enterprise#109047
This update improves the security of ESG management by separating ESG user access from accounting data. Previously, ESG users automatically had full accounting access, creating potential risks. Now, ESG users have restricted access, allowing organizations to control data visibility and adhere to confidentiality requirements.
Original PR description
Purpose: In some corporate structures, the ESG manager should not have the rights to access all details in the accounting apps (bank journals, invoices etc), for reasons of confidentiality. The idea is to let the user decide whether the ESG manager should have all rights (then put him as ESG Administrator) or restricted/read only rights (then put him as ESG User). Before this PR, once a user got the ESG user role, they also got the accounting user role, which gave them access to all the accounting features. This was not ideal, as it could lead to security issues. After this PR, the ESG user role no longer inherits from the accounting user role by default. It involves that we make some adjustments to the ESG dashboard and emissions views to ensure that they still work correctly without the accounting user role. task-6127245
This update addresses a technical change within the ChatGPT plugin for Odoo Enterprise. The plugin's formatting functionality has been updated to align with a recent API change, ensuring continued compatibility and proper operation. This ensures the plugin continues to function correctly.
Original PR description
The format plugin's shared removeFormats was renamed to removeSelectionFormats. task-6216233 community: https://github.com/odoo/odoo/pull/266372
This update resolves an issue where recurring plans were incorrectly removed from the website when updating product quantities. The fix ensures that recurring plan selections remain active even after changes to the product's price or variant, improving the subscription experience for users. This was caused by a misinterpretation of the 'allow_one_time_sale' flag.
Original PR description
# Introduction note This PR fixes two bugs introduced by the same commit : https://github.com/odoo/enterprise/commit/106d70a1ef0ddbd61a74b7cac82dfce1e316beaa The original commit fixed multiple issues…
# Introduction note This PR fixes two bugs introduced by the same commit : https://github.com/odoo/enterprise/commit/106d70a1ef0ddbd61a74b7cac82dfce1e316beaa The original commit fixed multiple issues regarding the display of recurring plans when the One-time purchase option was enabled, but it also introduced new ones. Theses new issues are due to multiple new checks on `allow_one_time_sale`, but this variable only indicates that the One-time purchase option is available to the user, not that it is actually selected. So the fixes of the original commit works when first loading the page, but fails when the content of the page is updated. # Shared steps - Activate Subscriptions & eCommerce modules - Create a subscription product, enable 'Accept One-Time' and publish it on the website # Bug 1 ## How to reproduce - Add atleast two recurring plans to the product - Go to the product page on the website - Select one of the recurring plans - Increase the quantity of the product ## The problem The recurring plan selection is removed ## Cause The condition `!combination_info.allow_one_time_sale` was added on the `t-att-checked` of the recurring plan selection display. This correctly fixed the issue when first loading the page, but when the user changes the price or the variant, the recurring plan are recomputed and rerendered : https://github.com/odoo/enterprise/blob/0b408acbadb2cfcbc844521f3244a06b7ae7be22/website_sale_subscription/static/src/interactions/product_page.js#L37-L40 When that is the case, that condition blocks the proper display of the selected recurring plan. ## Proposed Solution When loading the recurring plan selection, what defines wich plan is selected is the `subscription_default_pricing_plan_id` variable, which is based on the `plan_id` value given in the request to the server : https://github.com/odoo/enterprise/blob/0b408acbadb2cfcbc844521f3244a06b7ae7be22/website_sale_subscription/models/product_template.py#L222 We make it so if no `plan_id` is sent to the server and `allow_one_time_sale` is enabled, then the server does not give back any `subscription_default_pricing_plan_id` opw-6131532 # Bug 2 ## How to reproduce - Add an attribute with values A & B for the product - Define atleast two recurring plans for the variant with attribute B - Publish the product - Go to the product page - Select the variant with attribute B ## The problem The recurring plan is not displayed. If the order of the attribute is reversed, then it works as expected. ## Cause The pricings are correcly sent to the front-end but they are not added to selection because of the check on `allow_one_time_sale` : https://github.com/odoo/enterprise/blob/0b408acbadb2cfcbc844521f3244a06b7ae7be22/website_sale_subscription/static/src/interactions/product_page.js#L42-L50 opw-6132160 Forward-Port-Of: odoo/enterprise#120873 Forward-Port-Of: odoo/enterprise#115446
This update resolves a crash that occurred when creating payslips for employees in Belgium with overtime. The issue stemmed from a data structure mismatch during payslip generation, specifically related to overtime calculations. The fix removes a problematic function and corrects the data handling to ensure accurate overtime pay processing.
Original PR description
When creating a payslip for an employee in the Belgian localization with an hourly wage and an attendance-based work entry source contract, a traceback occurs if there is an attendance with overtime.…
When creating a payslip for an employee in the Belgian localization with an hourly wage and an attendance-based work entry source contract, a traceback occurs if there is an attendance with overtime. This happens because the overridden `_preprocess_work_hours_data_split_half` method in `l10n_be_hr_payroll_attendance` attempts to unpack `work_entries` assuming it is a list of triplets, but it is passed as a `defaultdict` with composite keys instead. This data structure mismatch results in a `ValueError: not enough values to unpack (expected 3, got 2)`. Even if updated to handle the `defaultdict` structure, `_preprocess_work_hours_data_split_half` would improperly delete the overtime line hours without adding them back elsewhere (the code responsible for adding them back seems to have been removed). Since this function serves no purpose anymore, we omit the call to it. However, because `saas-19.2` is a stable version Task Id: 6253707 Forward-Port-Of: odoo/enterprise#119177 Forward-Port-Of: odoo/enterprise#118676
This update resolves a problem where validating rental orders for kit products (specifically, products with a component BOM) would trigger an error. The fix ensures that the system correctly handles the explosion of the kit BOM during validation, preventing the 'record does not exist' error. This ensures rental orders involving kit products function as expected.
Original PR description
### Steps to reproduce: - Enable rental transfer - Create a rentable product R - Create and confirm a rental order for 1 unit of R - Create a kit bom for R: 1 x COMP - Validate the delivery of your…
### Steps to reproduce:
- Enable rental transfer
- Create a rentable product R
- Create and confirm a rental order for 1 unit of R
- Create a kit bom for R: 1 x COMP
- Validate the delivery of your unit of R
#### > Missing Error: Record does not exist or has been deleted.
### Cause of the issue:
Confirming your rental order will generate a confirm moves of R. However, since at this point the product was not a kit, these will not be exploded. Now, the issue is that at validation The move will be exploded and deleted in the super call:
https://github.com/odoo/enterprise/blob/7cceddaf086d849b8e2121e1023ef3479397534f/sale_mrp_renting/models/stock_move.py#L10-L13 https://github.com/odoo/odoo/blob/0f2f222a431627a672daf10c86ec2578a27f97bb/addons/mrp/models/stock_move.py#L550-L555 https://github.com/odoo/odoo/blob/0f2f222a431627a672daf10c86ec2578a27f97bb/addons/mrp/models/stock_move.py#L591-L593 However, since the overrides of the sale_{mrp,stock}_renting modules call self rather than the result of the super call, they still expect to work with the original move rather than its exploded result: https://github.com/odoo/enterprise/blob/7cceddaf086d849b8e2121e1023ef3479397534f/sale_mrp_renting/models/stock_move.py#L10-L13 https://github.com/odoo/enterprise/blob/7cceddaf086d849b8e2121e1023ef3479397534f/sale_stock_renting/models/stock_move.py#L61-L65
opw-6191841
Forward-Port-Of: odoo/enterprise#120866
Forward-Port-Of: odoo/enterprise#120051This update fixes an issue where the 'Consolidation' filter wasn't visible on multi-company General Ledger reports. The change ensures the filter appears by defaulting to the report's grouping settings, improving reporting accuracy and providing a more complete view of financial data.
Original PR description
The Consolidation filter doesn't appear on the General Ledger, even in multi-company. Since `user_groupby` can also be defined on the `account.report`, this commit adapts the logic for `show_consolidation`, to fallback to the report's groupby. no-task Forward-Port-Of: odoo/enterprise#120533
This update streamlines the process for submitting account returns by focusing validation and submission locking on the final stage. Previously, returns required a validation step before submission; now, the system automatically locks returns for submission once validation is complete, ensuring data accuracy and a more efficient workflow.
Original PR description
task-6167737
This update corrects inconsistencies between Odoo module manifests and actual file usage. The changes ensure that all dynamically loaded files are properly listed, and outdated files have been removed, resolving warnings flagged by the Odoo linter. This improves the stability and maintainability of the core Odoo Enterprise modules.
Original PR description
Since that they are already loaded from python scripts
This update corrects a technical issue preventing the 'Invoicing & Banks' user group from accessing the necessary data within the account reports module. The missing access control record was corrected, ensuring proper functionality for this user group. This resolves a potential restriction on reporting capabilities.
Original PR description
The `ir.model.access` giving read access to model `account.return` for group "Invoicing & Banks" hasn't been migrated properly.
This update fixes an issue where preparation times weren't accurately calculated when order stages changed and where reports incorrectly included data from all companies. The changes ensure preparation times are correctly updated and that reports now only display data for the active company, leading to more reliable order time tracking.
Original PR description
Issues: - Preparation time for order lines was not computed when the preparation order stage changed. - Preparation time report aggregated orders across all companies instead of showing records for the active company only. Fixes: - Ensure preparation time is properly recomputed when the order stage changes. - Add company domain filtering to the preparation time report. Task-6250974 Forward-Port-Of: odoo/enterprise#118738
This update fixes an issue where custom fields linked to employee or applicant records weren't automatically updating after a signature was completed. The fix ensures that these fields are correctly synchronized, allowing for accurate record-keeping. This improves the reliability of the signature process.
Original PR description
Version - saas-19.3 Steps to Reproduce: 1. Create a custom Sign field (e.g. "Passport No") with "Update Field" enabled, linked to Employee (For Applicant, same any custom field). 2. Employee flow:…
Version - saas-19.3 Steps to Reproduce: 1. Create a custom Sign field (e.g. "Passport No") with "Update Field" enabled, linked to Employee (For Applicant, same any custom field). 2. Employee flow: Employee app -> open an employee -> gear icon -> Signature Request -> send. Applicant flow: Recruitment app -> Applicants list view -> select an applicant -> Actions -> Signature Request -> send. 3. Complete the signature. 4. Check the linked record's "Passport No" field -> field is not updated. Issue: The field linked to the employee/applicant record is not updated after signing. Cause: Both the `hr.contract.sign.document.wizard` and `hr.recruitment.sign.document.wizard` create the `sign.request` in `validate_signature()` without setting `reference_doc`. `_get_auto_field_target_record()` relies on `reference_doc` to resolve the record to sync auto fields against. With `reference_doc` empty, it returns `None`, so `sign.request._sync_auto_field_value()` skips the item before it ever reaches the write step. Solution: Set `reference_doc` to the corresponding `hr.employee`/`hr.applicant` record when building the `sign.request` values in `validate_signature()`, so auto fields linked to those models can resolve their target record and sync back normally after signing. taskid-6308532 Forward-Port-Of: odoo/enterprise#121152
This update corrects an issue where task buffers weren't being applied correctly during rescheduling, particularly with multiple dependencies. The fix ensures that buffers are calculated and respected accurately, preventing tasks from overlapping and maintaining project timelines. This improves the reliability of the project scheduling feature.
Original PR description
Steps to reproduce: ---------------------------------------- - Have the company calendar work from 9 to 17 on weekdays - In project gantt view, create tasks with dependencies like this: ``` - [Task…
Steps to reproduce:
----------------------------------------
- Have the company calendar work from 9 to 17 on weekdays
- In project gantt view, create tasks with dependencies like this:
```
- [Task 1] (June 08, 09:00 AM - 10:00 AM) ──┐
├─> [Task 3] (June 11, 09:00 AM - 10:00 AM)
- [Task 2] (June 10, 09:00 AM - 10:00 AM) ──┘
```
- Make sure the "Auto-Reschedule (Keep Buffer)" is selected
- Then reschedule task 1 to `(June 09, 09:00 AM - 10:00 AM)`
- Task 3 is rescheduled to `(June 15, 09:00 AM - 10:00 AM)`
**Expected behavior:**
To respect the buffers, task 3 should have been rescheduled to `(June 12, 09:00 AM - 10:00 AM)`:
- The buffer from task 1 is 23 working hours after `June 09, 10:00 AM` is `June 12, 09:00 AM`
- The buffer from task 2 doesn't affect the rescheduling.
Cause:
----------------------------------------
From `_web_gantt_update_next_candidates_dates()` we call `_get_new_dates()` with `seconds_between_tasks` being the duration of working hours between the end of task 1 and the start of task 3. We also call it with `first_possible_start_date_per_candidate` being the end of task 3 also depends on task 2.
Then `_get_new_dates()` counts the working hours from `first_possible_start_date_per_candidate` until it reaches `seconds_between_tasks`. Which means the buffer between task 1 and task 3 is actually applied between task 2 and task 3.
Solution:
----------------------------------------
The value contained in `first_possible_start_date_per_candidate` is irrelevant, the correct value to give to `_get_new_dates()` would be `compute_end_date` as we want to keep the buffer to be calculated from this datetime.
So we create a fake dictionary with only the task and `compute_end_date` and give it to `_get_new_dates()`.
The same logic applies when moving tasks backwards.
opw-5973597
Forward-Port-Of: odoo/enterprise#119161This update significantly speeds up appointment scheduling, particularly when managing a large number of resources (like tables in a restaurant). The change optimizes how available resources are checked, reducing processing time by up to 70% in scenarios with many linked resources. This results in a faster and more responsive user experience.
Original PR description
In the current code, for each slot, and for each "available" resource, we check if the resource is available on the slot, based on availability values. Then, we check the remaining capacity of that…
In the current code, for each slot, and for each "available" resource, we check if the resource is available on the slot, based on availability values. Then, we check the remaining capacity of that resource. Also, linked resources information is added when computing the original resource remaining capacity. If many linked resources exist, this will be done several times and is not useful. This commit makes that loop disappear. We now check all resources at once in terms of availability, and linked resources that could be selected (in the appointment resources, in the slot resources (if any restricted resource)) at the same time. Then, the total capacity is the sum of the resource remaining capacity and the ones of available linked resources. Therefore, _slot_availability_is_resource_available is renamed to _slot_available_resources, as it now takes more than one resource and returns all resources among 'resources' that are valid on the slot, based on the availability_values, slot restrictions and booking lines. A noticeable difference is mainly seen when using many resources (and linked resources). For instance, a restaurant with a lot of small tables will have their slot availability check much shorter. BENCHMARK, LOCAL (time only, as number of requests does not change) Only appointment installed For a restaurant with - 10 tables of 2 - 5 tables of 2 linked, 2 times - 10 tables of 4 - 2 table of 2 - time then auto assign On loading /appointment/id: ~ 3.1s -> ~ 1.6s On selecting any number of people (1 to 10): [2s, 2.5s] -> [0.6s, 0.8s] Task-4144524 Forward-Port-Of: odoo/enterprise#121212 Forward-Port-Of: odoo/enterprise#107711
Features or functions removed from Odoo
This change removes a flag used to track production environments within the VoIP system. Previously, call records were always created, regardless of whether the system was initialized with demo data. This update ensures that call records are only created when demo data is present, streamlining the system and improving efficiency.
Original PR description
`is_production` is not very useful in a production database. Remove it. When a database is initiated without demo data, we don't create voip.call record for any call made in demo mode. When a database is initiated with demo data, no change, we still create voip.call record in all cases. Task-[6304061](https://www.odoo.com/odoo/5778/tasks/6304061)
Code cleanup and technical improvements
This update adjusts the way attachments are displayed within the accounting module. It adapts to a recent change in how attachment views are defined, ensuring consistent and accurate presentation of attached documents. This improves the user experience for managing financial records.
Original PR description
task-6263903
This update replaces an outdated JavaScript class (`Deferred`) with a modern equivalent (`Promise.withResolvers()`) across the Odoo codebase. This change improves code efficiency and aligns with current JavaScript standards, ensuring the system remains up-to-date and performs optimally.
Original PR description
…lvers()` The custom `Deferred` class is now obsolete. This commit replaces all instances and calls of `Deferred` across the codebase with the native, modern JavaScript equivalent: `Promise.withResolvers()`. task-5258181