Daily updates from Odoo
Monday, May 11, 2026
234 changes
14 changes
Resolved issues and error corrections
This update resolves a visual issue within the Time Off Type settings, specifically when the 'Allow Negative' option is selected. The change involved restructuring the form layout to correct a broken display, ensuring the Time Off Type settings are presented correctly. This improves the user experience for managing time off requests.
Original PR description
Version: - saas-19.3 Steps to reproduce: - Install the Time Off module - Go to Settings → Time Off Types - Click on “Allow Negative” Issue: - The form layout for Time Off Type is broken Cause: - Before this PR: https://github.com/odoo/odoo/pull/249288 , the Allow Negative field was inside a <group> tag. - After the PR, it was moved inside a <div>. Fix: - Updated the class based on the new structure to fix the layout Task-6127402
This update resolves an issue where self-billing invoices were incorrectly processed as standard invoices. The change ensures the correct document type ('credit_note') is used when generating UBL invoices for Peppol self-billing transactions, improving the accuracy of financial reporting. A demo environment setup has also been added.
Original PR description
To reproduce: - Activate Peppol - Activate selfbilling on your purchase journal - Create a Vendor Refund - Generate the UBL => The InvoiceTypeCode is 389, meaning it's considered a selfbilling invoice, not a selfbilling credit note. The issue is that we never put the document type of credit_note for selfbilling documents as it wasn't expected. invoice was, due to a else encompassing invoices and bills. Also add a handle demo to be able to create selfbilling documents in demo mode. opw-6132226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263128 Forward-Port-Of: odoo/odoo#260941
This update removes a restriction that previously required Lazada products to be 'storable'. When stock synchronization with Lazada is disabled (as is common), tracking stock levels isn't needed, so this restriction is no longer relevant. This change simplifies product setup for Lazada listings.
Original PR description
Lazada items previously required products to be of type 'storable'. This restriction is unnecessary when stock synchronization is disabled, since no stock tracking is performed in that case. opw-6173986 Forward-Port-Of: odoo/enterprise#116543
This update resolves an issue where the automatic checkout feature would fail when an employee had multiple overtime entries on the same day, particularly when one entry lacked a defined checkout time. The fix ensures accurate calculation of overtime durations, preventing validation errors and ensuring the feature functions correctly across various scenarios.
Original PR description
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action…
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action `Attendance: Automatically check-out employees`, an error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Reproduction Steps 1. Create an employee. Set their timezone to UTC and the Overtime Ruleset to Default Ruleset in the settings tab. In the Payroll tab, set a contract start date. 2. Set their Working Hours to a fixed 40 hours/week. Set the timezone of the Working Schedule to UTC. 3. Go to attendances and create 2 attendances on a Sunday: one from 06:00 to 06:01 and a second that starts at 06:02 but that doesn't have a checkout date. 4. Go to Settings and enable Automatic Checkout. Leave the Tolerance to 2 hours. 5. Enable debug mode and go to Scheduled Actions. Look for `Attendance: Automatically check-out employees` and run it manually. ### Expected behavior As the tolerance is 2 hours, the second attendance check-out time should be set at 08:01. ### Unexpected behavior An error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Origin of the issue We retrieve overtime intervals with the domain: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_version.py#L34-L42 This will make us retrieve all the overtimes for a given day, even if overtimes belong to different attendances. However, this means that we will retrieve several times the same overtimes, as this piece of code is executed in this context: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L35 https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L43 This results in the generation of intervals containing multiple times the same overtimes. We then sum their duration to later create work entries: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L47 As we try to create a work entry with too much overtime, that exceeds 24 hours, it raises a validation error. Moreover, as the overtime hours are always stored in UTC, it makes sense to always keep the timezone as UTC when performing a `_read_group` . __ opw-6036064 Forward-Port-Of: odoo/enterprise#116194
This update fixes an issue where the navbar menu items and app icon would disappear when users zoomed out or increased the screen width on mobile devices. The fix ensures the navbar dynamically adjusts to display the full menu and icon when sufficient screen space is available, improving the user experience.
Original PR description
**Issue:** In the navbar view, when a user starts in mobile view (narrow width) and then increases the screen width (e.g., by zooming out or resizing), the menu items and app icon do not reappear.…
**Issue:** In the navbar view, when a user starts in mobile view (narrow width) and then increases the screen width (e.g., by zooming out or resizing), the menu items and app icon do not reappear. The navbar remains stuck in mobile mode even when there is enough space to display the full layout. **Fix:** The navbar was relying on `env.isSmall`, which is only set during initialization and does not react to window resizing. This has been updated to use `this.ui.isSmall`, which is reactive and updates dynamically when the viewport size changes. **Before:** After resizing from mobile to a larger width, the navbar continued to behave as if it were still in mobile view, keeping menu items and the app icon hidden. **After:** When the screen width increases, the navbar correctly detects the change and re-renders, restoring the menu items and app icon as expected. opw-6107660 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263675 Forward-Port-Of: odoo/odoo#263039
This update ensures that 'Back on' messages for employees on holiday are now consistently displayed in both the standard and compact versions of the chat sidebar. Previously, these messages were only visible in the larger sidebar view. This enhancement provides a more complete and user-friendly experience for viewing team availability.
Original PR description
Before this commit, the "Back on X" text below chats of people that are away was only displayed in non-compact sidebar. This comes from `xpath` that targets only the non-compact sidebar. This commit fixes the issue by adding the `xpath` for the compact sidebar. Task-6197362 Before / After <img width="247" height="254" alt="before" src="https://github.com/user-attachments/assets/da149668-7649-479a-baca-c3df9f6600b6" /> <img width="240" height="279" alt="after" src="https://github.com/user-attachments/assets/072405d1-b050-4314-933f-31f1c1c30ad4" /> Forward-Port-Of: odoo/odoo#263426 Forward-Port-Of: odoo/odoo#263071
This update fixes an issue where products added to a sales order catalog were appearing in the wrong order. The change ensures products are added to the catalog in the intended sequence, improving the user experience when managing product selections. This resolves a bug related to how the system adds new order lines to the catalog.
Original PR description
# How to reproduce
- Create product n1 & n2
- Create a SO
- Add a section to that SO
- Go to the catalog
- Ensure the section is selected, then add product n1 followed by n2
# The problem
The orders of the product are reversed. n2 is before n1 in the SO
# Cause
Clicking on the Add button will trigger an RPC call to "/product/catalog/update_order_line_info"
that will endup adding a new sale order line :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/sale/models/sale_order.py#L2222-L2227
To determine the sequence of this new order line, we call `_get_new_line_sequence`.
Since a section_id is given, the new order line is inserted right after, before any
product under the same section :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/account/models/product_catalog_mixin.py#L59-L63
opw-6175704
Forward-Port-Of: odoo/odoo#262556This update resolves a crash issue that occurred when creating Point of Sale (POS) orders with the pos_avatax module installed. The fix re-enabled a method that correctly identifies the customer's shipping information, ensuring POS order creation remains stable. This improves the reliability of the POS system for our users.
Original PR description
Before this commit, when pos_avatax was installed, creating a pos order could crash because the pos order does not have the partner_shipping_id field. This commit re-adds the _get_avatax_ship_to_partner method as it was before the refactor https://github.com/odoo/enterprise/commit/0404086db567ee0595414263d36a3b7dceaa0dbe, which returns the partner_id for the pos order. The `_get_avatax_ship_to_partner` is overridden in `pos_avatax`. Since a `pos.order` does not have a `partner_shipping_id`, the overridden function only reads the partner_id. opw-6122280 Forward-Port-Of: odoo/enterprise#116682 Forward-Port-Of: odoo/enterprise#115840
This update resolves an issue where removing a recruiter from a job position would corrupt links between employees and their user accounts within Odoo. The fix ensures that recruiter assignments are correctly updated across all related applications, preventing data inconsistencies and ensuring accurate user management.
Original PR description
**Steps to Reproduce:** 1. Click on configure on one of the job positions having a recruiter assigned. 2. Remove the recruiter from the form 3. Now try to go to Settings App > Manage Users. (You will…
**Steps to Reproduce:**
1. Click on configure on one of the job positions having a recruiter assigned.
2. Remove the recruiter from the form
3. Now try to go to Settings App > Manage Users. (You will stuck with an error)
4. Navigate to users using the menu, and open Mitchell Admin → He is no longer an employee.
**Bug Cause:**
In HrJob.write(), when recruiter_id changes, the code attempts to update ongoing applications' recruiter by writing:
application_ids.recruiter_id.user_id = job.recruiter_id.user_id
This traverses the relational chain and writes user_id directly on the existing recruiter employee record instead of reassigning the recruiter on the applications. When recruiter_id is cleared, job.recruiter_id.user_id resolves to False, effectively setting user_id = False on the previous recruiter's hr.employee record, breaking the link between the employee and their user account.
**Bug Solution:**
Directly reassign recruiter_id on the ongoing applications instead of mutating the employee's user_id: application_ids.recruiter_id = job.recruiter_id
**Task:** 6102209
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#257836This update resolves a technical issue preventing subscription invoices from calculating correctly in version 19. The problem stemmed from a mismatch in data types when comparing dates, specifically when determining if an invoice should be generated. The fix ensures accurate invoice generation for subscription orders.
Original PR description
**Steps-to-Reproduce** - In v19, install subscriptions. - create new subscription + service product with allow one time sale enabled. - make a SO with that product,any reccuring plan and any end…
**Steps-to-Reproduce**
- In v19, install subscriptions.
- create new subscription + service product with allow one time sale enabled.
- make a SO with that product,any reccuring plan and any end date.
```
id | name | subscription_state | next_invoice_date | end_date
----+--------+--------------------+-------------------+------------
1 | S00001 | 1_draft | | 2026-05-02
```
- confirm the SO
```
id | name | subscription_state | next_invoice_date | end_date
----+--------+--------------------+-------------------+------------
1 | S00001 | 3_progress | 2026-05-01 | 2026-05-02
```
- remove its recurring plan (some product sold for months for testing then converted to one time sale )
```
id | name | subscription_state | next_invoice_date | end_date
----+--------+--------------------+-------------------+------------
1 | S00001 | 3_progress | | 2026-05-02
```
- upgrade to v19.1 will fail or opening sales > To Invoice > Orders To Invoice gives this error or add amount_to_invoice in list view using studio to produce in v19 :
```
File "/home/odoo/odoo18/enterprise/sale_subscription/models/sale_order_line.py",
line 175, in _compute_amount_to_invoice
and (not order.end_date or order.next_invoice_date < order.end_date)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'bool' and 'datetime.date'
```
- upgrade failing for v19.1 because amount_to_invoice added to list view [here](https://github.com/odoo/odoo/commit/427232efd121410380b62acf4fd2e9ee369e6542#diff-48cb4309a6006f91b2b40e4c1049860218d419fce1782c7dcc278329803129caR193-R213).
upg - [4220658](https://upgrade.odoo.com/odoo/upgrade.request/4220658)
opw - [6128033](https://www.odoo.com/odoo/project/70/tasks/6128033)
Forward-Port-Of: odoo/enterprise#115976This update enhances the tracking of errors within Odoo's Point of Sale system. Previously, IndexedDB errors weren't consistently recorded, making it difficult to diagnose issues. Now, critical IndexedDB errors are saved to local storage, ensuring that error traces are preserved even if the main IndexedDB system is temporarily unavailable, aiding in faster troubleshooting.
Original PR description
Add a `persistToStorage` flag to `logPosMessage` that mirrors critical IndexedDB errors to `localStorage["pos_idb_errors"]` in addition to the posLogger. This ensures error traces are preserved even when the IndexedDB daemon itself is unavailable. opw-6150816 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263377 Forward-Port-Of: odoo/odoo#263093
This update resolves a crash issue that could occur when displaying data in Odoo's graph views. The fix ensures that a necessary data element is always available, preventing errors during data formatting and improving the overall stability of the graph view functionality. This change enhances the reliability of reporting and data visualization within Odoo.
Original PR description
**Current behavior before PR:** In graph rendering, `formatValue()` delegates to widget formatters (e.g., formatPercentage), which call `extractOptions()` (from formatFloat). That function directly accesses `attrs.digits`, assuming `attrs` is defined. Here, `extractOptions()` could be called without `attrs`, leading to a traceback when accessing `attrs.digits`. **Desired behavior after PR is merged:** This commit ensures `attrs` is always defined when calling `extractOptions()`, avoiding the crash. task-[6023555](https://www.odoo.com/odoo/project/1519/tasks/6023555) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262003
This update resolves an issue where the Odoo website crashed when rental products had overlapping closed days and public time off periods. The fix simplifies the availability check to focus solely on time ranges, ensuring the website correctly displays rental availability without errors. This improves the user experience for rental product browsing.
Original PR description
Steps to reproduce: - Install website_sale_renting_planning. - Create a rental service product linked to a planning role. - Enable Sync Shifts and Rental Orders on that role. - Add a two-day public time off on the working calendar. - Open the product on the website with overlapping dates. Current behavior: The shop crashes when the selected dates overlap a closed day and a public time off. Expected behavior: The website should show rental availability without crashing when both cases overlap. Issue: The availability flow mixed two kinds of calendar data while it only needed time ranges, so the overlap broke the website flow. Fix: Keep the unavailability check focused on time ranges for closed days and public time off so both cases can be combined safely. Ref: odoo/enterprise#98165 odoo/enterprise#102070 odoo/enterprise#102076 task-6164218 Forward-Port-Of: odoo/enterprise#115480
This update corrects a discrepancy in how the dashboard displays On-Time Delivery (OTD) rates. Previously, a slight timing difference between purchase order dates and the dashboard's calculation resulted in an inaccurate 0% OTD. This fix aligns the dashboard's OTD calculation with the partner's on-time rate, ensuring accurate reporting.
Original PR description
# Setup For easiness of testing : have no purchase order in your dashboard # How to reproduce - Create a Purchase Order for Vendor X and with Product Y - Click on Confirm Order -> Receive -> Validate…
# Setup For easiness of testing : have no purchase order in your dashboard # How to reproduce - Create a Purchase Order for Vendor X and with Product Y - Click on Confirm Order -> Receive -> Validate - Go back to the dashboard # The problem The displayed OTD is 0%, but when you go to the Vendor X form view and check his On-time Rate, it is 100% # Cause The computation for the On-time rate in the dashboard uses the whole datetime value, so if there is even a second of difference between `effective_date` and `date_planned`, the PO is not counted as on-time : https://github.com/odoo/odoo/blob/942cbbbf243ff28f84fdaa40ed73b6572e0032a6/addons/purchase_stock/models/purchase_order.py#L253 That is not the case for the partner On-time rate computation, where we round the datetime value to the date value : https://github.com/odoo/odoo/blob/942cbbbf243ff28f84fdaa40ed73b6572e0032a6/addons/purchase_stock/models/res_partner.py#L57 opw-6128510 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263341 Forward-Port-Of: odoo/odoo#260384
17 changes
Resolved issues and error corrections
This fix addresses a misleading warning displayed during production runs when components aren't applicable to the selected product variant. The change introduced in version 19.2 incorrectly processed BoM lines, leading to these warnings. The update refines the filtering logic to accurately exclude irrelevant components, preventing these confusing alerts.
Original PR description
Currently when the user produces a product, the system shows warnings for components that don't apply to that variant. ## Steps to replicate: - Install Manufacturing - Enable Variants from settings -…
Currently when the user produces a product, the system shows warnings for components that don't apply to that variant. ## Steps to replicate: - Install Manufacturing - Enable Variants from settings - Create a Product 'Car' with color attribute value: Red and Blue - Create Bill of material for car: - Components: Engine, Radiator - For the 'Engine' component set color: Blue on 'Apply on Variants' field on bom lines (unhide the field as it is hidden by default). - Create and confirm an MO for Red Car - Produce All ## Observed Behavior: A consumption warning is being triggered indicating that the radiator has not been consumed, even though this component is intended only for the blue car variant and not the red car. ## Root cause: When the Produce All button is pressed, it calls the `button_mark_done` function, which in turn invokes `pre_button_mark_done` as shown in [1]. This eventually leads to the execution of `_get_consumption_issues` as shown at [2]. The issue arises in the loop at [3], where BoM lines are checked for missing components. The filtering logic used to populate the `all_lines` variable incorrectly includes BoM lines that belong to other variants. Specifically, it does not take into account the "Apply on Variants" field, causing lines meant for different variants to be considered. As a result, these irrelevant lines are treated as missing components and are added to the `missing_lines`, which is then included in the issues list at [4]. **Why this did not occur in versions prior to 19.2?:** This behavior was introduced unintentionally after [commit]( https://github.com/odoo/odoo/commit/7a406f26c3c846b347498a3cb60b4ac12df53c6e), which revamped the warning wizard to support showing warning without a BoM. Previously, the expected component values were derived solely from `_get_moves_raw_values`. However, after the change, the logic also considers BoM lines directly. This change led to the inclusion of variant-specific lines without properly filtering them based on the `"Apply on Variants"` field, resulting in the observed issue. [1]: https://github.com/odoo/odoo/blob/4f04f26886393843cfdcec97ed1248a8cf0d1957/addons/mrp/models/mrp_production.py#L2214-L2227 [2]: https://github.com/odoo/odoo/blob/4f04f26886393843cfdcec97ed1248a8cf0d1957/addons/mrp/models/mrp_production.py#L2348-L2366 [3]: https://github.com/odoo/odoo/blob/5b907e1235e37b2e6f90ac3289d1947f1abd57df/addons/mrp/models/mrp_production.py#L1763-L1781 [4]: https://github.com/odoo/odoo/blob/5b907e1235e37b2e6f90ac3289d1947f1abd57df/addons/mrp/models/mrp_production.py#L1811-L1813 ## Solution: To prevent confusion, users should not see warnings for component lines that are not applicable to the current product variant. This can be achieved by refining the filtering logic to exclude irrelevant BoM lines, using the `_skip_bom_line` which ensures that only BoM lines valid for the current product variant are considered. By tightening this condition, variant-specific components that do not apply to the selected variant will be ignored, thereby avoiding incorrect consumption warnings. opw-6086167
A bug in the product creation test for the SOL editable form was preventing the correct default value ('no') for the expense policy from being set. This fix ensures that new products created through this test process initialize the expense policy correctly, resolving a validation error. This improves the reliability of product creation tests.
Original PR description
When creating an on-the-fly product in the SOL editable form test, expense_policy was not initialized to its default value ('no') on the transient record created with `new()`.
This happens because `new()` only initializes defaults for fields needed by the current form view (required fields, modifiers, onchanges, etc.), and expense_policy is not part of them in this flow.
Also Since `product_id.expense_policy` is also not a dependency of `qty_delivered_method`, the compute keeps using the incorrect initial value, causing the readonly assertion on `qty_delivered` to fail.
Fix by explicitly passing the expense_policy's default value in the product creation values.
runbot error-239939
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update resolves an issue where the cursor wasn't correctly positioned after inserting a code block within a list. The fix eliminates a technical glitch that created an invisible text node, ensuring the editor accurately restores the cursor's location. This improves the overall user experience when working with code blocks.
Original PR description
#### Description of the issue this PR addresses: - In shortcut plugin, extractContent leaves an empty text node at block start - When converting to a code block, that invisible node is removed, so the editor cannot restore the cursor correctly #### Desired behavior after PR is merged: - Delete the selection directly instead of extracting text - This prevents creating the invisible empty node #### Steps to reproduce: - Type `1. ` to create a list - Immediately insert `/code` - Cursor does not move inside the code block task-6169180 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263256 Forward-Port-Of: odoo/odoo#261799
This update resolves an error that prevented access to public departments when managing employees across multiple companies. Previously, a user wouldn't be able to view departments managed by employees defined in a different company. The fix ensures correct access permissions are granted, allowing users to manage departments regardless of employee company affiliation.
Original PR description
## Short functional explanation of the error When accessing a public department from a multicompany setting, an access error is triggered. ## Reproduction Steps 1. Create another company. 2. Go to…
## Short functional explanation of the error When accessing a public department from a multicompany setting, an access error is triggered. ## Reproduction Steps 1. Create another company. 2. Go to Employees and create an employee. 3. Go to Departments and create a Department. Set the manager of the department to the employee you just created. Make sure that this department doesn't have a company assigned. 4. Select the company you just created, and unselect the previous one. ### Expected behavior The public department should appear in the list. ### Unexpected behavior An error occurs: ```Uh-oh! Looks like you have stumbled upon some top-secret records. Sorry, Mitchell Admin (id=2) doesn't have 'read' access to: - Employee (hr.employee) ``` ## Origin of the issue In the case where we want to access departments but managers are employees only defined in one specific company, which isn't the current company, the access is denied as we try to access such employees. However, we should be able to access their departments as they're publicly visible. Therefore, in the code, we need to check if the employee we want to access is a manager from a department that is accessible. __ opw-6113535
This update resolves an issue where self-billing invoices were incorrectly processed as standard invoices, impacting Peppol compliance. The change ensures the correct document type ('credit_note') is used when generating UBL invoices for self-billing transactions, improving accuracy and adherence to regulations. A demo handle has also been added for testing.
Original PR description
To reproduce: - Activate Peppol - Activate selfbilling on your purchase journal - Create a Vendor Refund - Generate the UBL => The InvoiceTypeCode is 389, meaning it's considered a selfbilling invoice, not a selfbilling credit note. The issue is that we never put the document type of credit_note for selfbilling documents as it wasn't expected. invoice was, due to a else encompassing invoices and bills. Also add a handle demo to be able to create selfbilling documents in demo mode. opw-6132226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263128 Forward-Port-Of: odoo/odoo#260941
This update ensures that 'Back on' messages for employees on holiday are now consistently displayed in both the standard and compact versions of the chat sidebar. Previously, these messages were only visible in the larger sidebar view. This enhancement provides a more complete and user-friendly experience for all users.
Original PR description
Before this commit, the "Back on X" text below chats of people that are away was only displayed in non-compact sidebar. This comes from `xpath` that targets only the non-compact sidebar. This commit fixes the issue by adding the `xpath` for the compact sidebar. Task-6197362 Before / After <img width="247" height="254" alt="before" src="https://github.com/user-attachments/assets/da149668-7649-479a-baca-c3df9f6600b6" /> <img width="240" height="279" alt="after" src="https://github.com/user-attachments/assets/072405d1-b050-4314-933f-31f1c1c30ad4" /> Forward-Port-Of: odoo/odoo#263426 Forward-Port-Of: odoo/odoo#263071
This update corrects a previous issue where changing a recruiter on an ongoing job application didn't properly update the recruiter information for previously applied candidates. Now, updating the recruiter reflects the change across all active applications, ensuring accurate tracking and communication. This improves the efficiency of our recruitment process.
Original PR description
Followup of 05e22346050d, when changing recruiter on a job position only change the recruiter on the ongoing applicants, not the old recruiter employee's user. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a technical issue causing broken sponsor logos on event pages. The fix prevents the QWeb image widget from generating invalid image URLs by limiting the image sizes used in the sponsor footer cards. This ensures all sponsor logos display correctly and maintains a professional appearance.
Original PR description
Problem: Sponsor logos were broken on the event sponsor footer cards after https://github.com/odoo/odoo/commit/36e680feca4884940e020119de6a13cd7f927516, even when `image_128` / `image_512` were set. The QWeb image widget generated a `srcset` including larger sizes (`image_1024`, `image_1920`) that do not exist on `event.sponsor`, allowing browsers to pick invalid URLs. Cause: The template renders `sponsor.image_128` with the generic image widget, which auto-generates a `srcset` from the image family. Without restricting it, larger nonexistent variants are included. Solution: Set `t-options` with `"preview_image": "image_128"` in the sponsor footer template to limit `srcset` to existing variant and ensure valid image URL is selected. Task-6079695
A recent update introduced a one-hour delay when scheduling shifts in the Gantt day view. This was caused by a change in how timezone information was handled. The fix ensures that shift times are now accurately reflected based on the resource's timezone, resolving the scheduling issue.
Original PR description
Steps to reproduce:
-
- Open Planning
- Switch to Gantt day view
- Select a time slot from 1 PM to 3 PM for a resource
Issue:
-
- When creating a planning shift from the Gantt day view, the created shift has a 1 hour time lag compared to the selected slot.
Cause:
-
- In saas-19.2, the timezone field was removed from the resource calendar.
- _work_intervals_batch was called without resources_per_tz, causing it to default to {UTC: resource} instead of the correct resource timezone.
Solution:
-
- Pass the resource timezone when calling _work_intervals_batch so attendance times are stamped with the correct resource timezone instead of defaulting to UTC.
task-5966733This update resolves an issue that occurred when users attempted to merge a single mailing list. The fix addresses a technical error related to empty recordsets, preventing a database syntax error and ensuring the merge functionality works correctly.
Original PR description
Currently, error occurs when user tries to merge a mailing list. Steps to replicate: - Install `mass_mailing`. - Open Email Marketing > Mailing Lists > Mailing Lists and switch to list view. - Select…
Currently, error occurs when user tries to merge a mailing list.
Steps to replicate:
- Install `mass_mailing`.
- Open Email Marketing > Mailing Lists > Mailing Lists and switch to list view.
- Select a single record and Click merge.
Error:
```
psycopg2.errors.SyntaxError: syntax error at or near ")"
LINE 8: AND src_sub.list_id IN ()
^
ValueError: SyntaxError('syntax error at or near ")"\nLINE 8: 'AND src_sub.list_id IN ()\n'
^\n') while evaluating 'action = records.action_mailing_lists_merge()'
```
Cause:
- Error occurs due to a recent [PR].
- When the user selects only a single record, `self - dest` [1] evaluates to an empty recordset. As a result, `action_merge()` receives an empty `src_lists`.
- Later, this is used [here] and converted into an empty tuple, producing an invalid SQL clause like `src_sub.list_id IN ()`, which leads to this error.
Solution:
- When `src_lists` is an empty recordset, we early return from `action_merge()`.
[PR]: https://github.com/odoo/odoo/pull/72156
[1]: https://github.com/odoo/odoo/blob/4193b3735d64518290613f5c8132f1fd07afa229/addons/mass_mailing/models/mailing_list.py#L218
[here]: https://github.com/odoo/odoo/blob/4193b3735d64518290613f5c8132f1fd07afa229/addons/mass_mailing/models/mailing_list.py#L266
sentry-7447326420
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update ensures that all employees, regardless of access permissions, display the correct leave status icons (like 'Back on') in the IM status indicators. Previously, employees from inaccessible companies wouldn't show these icons, leading to a confusing user experience. The fix updates how employee data is fetched to account for multi-company scenarios.
Original PR description
* = hr_holidays Before this commit, when displaying the IM status icon for employees on leave of companies the user does not have access to, we would not display the `fa-plane` icon or the "Back on" indicator. Steps to reproduce: - Create a new company X - Create a new employee Y (with user) in company X - With a user who does not have access to company X open the General channel member list -> no leave icon, open the avatar card -> no icon This happens because since [1] the leave IM status icon is computed client side using the employee information, rather than computed on the `im_status` field itself. This however causes problem in a multi-company context due to the field `employee_ids@ResUsers` having a field-level domain restricting to the requesting user's active companies. This commit fixes the issue by fetching all of the user's employee_ids regardless of active company. [1] https://github.com/odoo/odoo/pull/210189 task-6191367
This update resolves an issue where the automatic checkout feature incorrectly triggered a validation error when an employee had multiple overtimes on the same day, particularly when one overtime lacked a defined end time. The fix addresses a technical problem with how overtime intervals are retrieved and processed, ensuring the feature now functions correctly and avoids the validation error.
Original PR description
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action…
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action `Attendance: Automatically check-out employees`, an error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Reproduction Steps 1. Create an employee. Set their timezone to UTC and the Overtime Ruleset to Default Ruleset in the settings tab. In the Payroll tab, set a contract start date. 2. Set their Working Hours to a fixed 40 hours/week. Set the timezone of the Working Schedule to UTC. 3. Go to attendances and create 2 attendances on a Sunday: one from 06:00 to 06:01 and a second that starts at 06:02 but that doesn't have a checkout date. 4. Go to Settings and enable Automatic Checkout. Leave the Tolerance to 2 hours. 5. Enable debug mode and go to Scheduled Actions. Look for `Attendance: Automatically check-out employees` and run it manually. ### Expected behavior As the tolerance is 2 hours, the second attendance check-out time should be set at 08:01. ### Unexpected behavior An error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Origin of the issue We retrieve overtime intervals with the domain: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_version.py#L34-L42 This will make us retrieve all the overtimes for a given day, even if overtimes belong to different attendances. However, this means that we will retrieve several times the same overtimes, as this piece of code is executed in this context: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L35 https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L43 This results in the generation of intervals containing multiple times the same overtimes. We then sum their duration to later create work entries: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L47 As we try to create a work entry with too much overtime, that exceeds 24 hours, it raises a validation error. Moreover, as the overtime hours are always stored in UTC, it makes sense to always keep the timezone as UTC when performing a `_read_group` . __ opw-6036064 Forward-Port-Of: odoo/enterprise#116194
This update fixes an issue where products added to a sales order catalog were appearing in the wrong order. The fix ensures products are added to the catalog in the intended sequence, improving the user experience when managing product selections. This resolves a discrepancy in how the system handles adding products to sections within the catalog.
Original PR description
# How to reproduce
- Create product n1 & n2
- Create a SO
- Add a section to that SO
- Go to the catalog
- Ensure the section is selected, then add product n1 followed by n2
# The problem
The orders of the product are reversed. n2 is before n1 in the SO
# Cause
Clicking on the Add button will trigger an RPC call to "/product/catalog/update_order_line_info"
that will endup adding a new sale order line :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/sale/models/sale_order.py#L2222-L2227
To determine the sequence of this new order line, we call `_get_new_line_sequence`.
Since a section_id is given, the new order line is inserted right after, before any
product under the same section :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/account/models/product_catalog_mixin.py#L59-L63
opw-6175704
Forward-Port-Of: odoo/odoo#262556This update resolves an issue where setting a maximum package weight in Sendcloud prevented accurate shipping rate calculations. The fix ensures that package splitting is handled correctly, allowing rates to be generated accurately even when package weights exceed the maximum deliverable weight. This improves the reliability of shipping cost estimations.
Original PR description
Issue ----- Putting a max weight on a package type causes getting a rate with Sendcloud to fail. Steps to reproduce ----- - Setup Mondial Relay using Sendcloud - Set a default package type with max…
Issue ----- Putting a max weight on a package type causes getting a rate with Sendcloud to fail. Steps to reproduce ----- - Setup Mondial Relay using Sendcloud - Set a default package type with max weight 2kg - Create a product with a 500g weight - Create a SO with the product - Add delivery - Sendcloud Mondial Relay - Get rate > Impossible to get a rate Cause ----- When retrieving the shipping method to use when retrieving a rate, we use the real weight of the order. https://github.com/odoo/enterprise/blob/cca1433f5a064673b8e007530e20e8a9fe72949b/delivery_sendcloud/models/sendcloud_service.py#L67 https://github.com/odoo/enterprise/blob/cca1433f5a064673b8e007530e20e8a9fe72949b/delivery_sendcloud/models/sendcloud_service.py#L81 However, when making the rate call, we use the value returned by `_split_shipping` https://github.com/odoo/enterprise/blob/cca1433f5a064673b8e007530e20e8a9fe72949b/delivery_sendcloud/models/sendcloud_service.py#L91 which is equal to the maximum weight of the package. This is blocking in some cases, like if - the real weight is 750g - the package max is 2kg - Sendcloud returns a shipping method for [500g;1kg] Asking a rate for this method & a 2kg package will fail (rightfully so). Solution ----- The shipment should be split into packages before retrieving the shipping methods. Otherwise the problem might be the other way around where we retrieve a shipping method for the whole order, only to split it into multiple packages because they don't fit in one. Also, the `shipping_weight` returned by `_split_shipping` should only be different from the order's total weight if it is higher than the maximum deliverable weight. ----- Ticket: opw-5947199 Forward-Port-Of: odoo/enterprise#116415 Forward-Port-Of: odoo/enterprise#108315
This update fixes an issue where the table menu options weren't updating when switching between target cells. The change ensures that the menu accurately reflects the current cell selection, providing a more reliable user experience. This improves the functionality of the HTML editor module.
Original PR description
After this commit [1], setup is executed only on the initial mount of the table menu and not on subsequent target cell changes. As a result, colItems, rowItems, and other values found in setup become stale, causing the menu to display options that do not reflect the current target cell. This commit moves the necessary values from setup into useEffect so they update correctly when the target cell changes. task-6111986 [1]: https://github.com/odoo/odoo/commit/7d523d6402c9bff3c2e4bcd0329f486a2d0f45ec Backport of Commit https://github.com/odoo/odoo/commit/729c45ddf3d1e377507d93997c5ca45984d64d75 Forward-Port-Of: odoo/odoo#262052 Forward-Port-Of: odoo/odoo#258590
This update fixes an issue where payment methods weren't correctly displayed for branch companies within Odoo. Previously, the 'Payment Method' field on partner and account move forms didn't show options from the parent company. Now, payment methods from the parent company are consistently available when working with branch companies, ensuring accurate financial processing.
Original PR description
**Steps to reproduce:** - Install Contacts and Accounting - Create a branch company - Switch to the branch company **Issue:** In the partner form, "Payment Method" field doesn't propose the methods coming from the parent company. Same issue on the account move form. However, in the payment wizard opened from an invoice, the payment methods from the parent company are available. The behavior should be consistent. The payment methods from the parent company should be available from a branch company opw-6001573 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260168
This change corrects a bug that prevented the gross salary line from appearing in the salary configurator for French-speaking users. The issue stemmed from a translation mismatch in how salary categories were defined and displayed, leading to incorrect data rendering. This fix ensures accurate salary calculations and presentation across all supported languages.
Original PR description
**Problem:** On a Belgian company with the UI set to French (or any non English language), the gross line never appears in the salary configurator sidebar when opening an offer. **Steps to…
**Problem:**
On a Belgian company with the UI set to French (or any non English language), the gross line never appears in the salary configurator sidebar when opening an offer.
**Steps to reproduce:**
1. Create a Belgian company.
2. Install French and set the admin user to French.
3. Go to an applicant (e.g Laurie Poiret), create a salary offer, save.
4. Open the offer link (salary configurator).
**Cause:**
The base `_get_compute_results` uses the translated `category_id.name` ("Salaire mensuel" in french) as the dictionary key when writing entries into `resume_lines_mapped`. The payroll override function `_get_period_name`, which for monthly schedules returned the hard coded english string `"Monthly Salary"` instead of the translated category name. This caused a key mismatch: the gross line was stored under the translated key, while the override rebuilt `resume_categories` with the english key so when the template iterates over categories and looks up `lines[category]`, the whole "Monthly Salary" bucket was invisible in every non english language.
**Solution:**
We should now return the `category_id.name` directly (the translated name coming from the record itself). This keeps all keys consistent between `resume_categories` and `resume_lines_mapped` regardless of the language used.
also because in https://github.com/odoo/enterprise/blob/1845042ff388593c4cdf547d47c018f42bd02c7c/l10n_be_hr_contract_salary/controllers/main.py#L450
We use `resume = result['resume_lines_mapped']['Monthly Salary']`
We need to re-design this by using the actual translated names, and building `result` keys based on the language selected (the same should be applied for "Yearly benefits").
opw-6009711
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/enterprise#116657
Forward-Port-Of: odoo/enterprise#11067618 changes
Resolved issues and error corrections
This update resolves an issue where the gross salary line was missing in the salary configurator when the user interface was set to a non-English language (like French). The fix ensures that the correct translated category name is used consistently, displaying the gross salary accurately for all users regardless of their language settings.
Original PR description
**Problem:** On a Belgian company with the UI set to French (or any non English language), the gross line never appears in the salary configurator sidebar when opening an offer. **Steps to…
**Problem:**
On a Belgian company with the UI set to French (or any non English language), the gross line never appears in the salary configurator sidebar when opening an offer.
**Steps to reproduce:**
1. Create a Belgian company.
2. Install French and set the admin user to French.
3. Go to an applicant (e.g Laurie Poiret), create a salary offer, save.
4. Open the offer link (salary configurator).
**Cause:**
The base `_get_compute_results` uses the translated `category_id.name` ("Salaire mensuel" in french) as the dictionary key when writing entries into `resume_lines_mapped`. The payroll override function `_get_period_name`, which for monthly schedules returned the hard coded english string `"Monthly Salary"` instead of the translated category name. This caused a key mismatch: the gross line was stored under the translated key, while the override rebuilt `resume_categories` with the english key so when the template iterates over categories and looks up `lines[category]`, the whole "Monthly Salary" bucket was invisible in every non english language.
**Solution:**
We should now return the `category_id.name` directly (the translated name coming from the record itself). This keeps all keys consistent between `resume_categories` and `resume_lines_mapped` regardless of the language used.
also because in https://github.com/odoo/enterprise/blob/1845042ff388593c4cdf547d47c018f42bd02c7c/l10n_be_hr_contract_salary/controllers/main.py#L450
We use `resume = result['resume_lines_mapped']['Monthly Salary']`
We need to re-design this by using the actual translated names, and building `result` keys based on the language selected (the same should be applied for "Yearly benefits").
opw-6009711
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/enterprise#110676This update fixes an issue where users were incorrectly directed to a standard form view when opening documents linked through a Studio-added Many2One field. Now, users can directly access the document's Kanban or List view, allowing them to preview and navigate the document content as intended. This enhances the user experience for document management.
Original PR description
Problem: When opening a linked `documents.document` record from a Many2One field added via Studio, the user is redirected to the standard form view. This is problematic because the form view does not allow the user to preview the actual document or navigate into it if the record is a folder. Solution: override `get_formview_action` to open the Kanban/List/Activity views. task-6068437 Forward-Port-Of: odoo/enterprise#116425 Forward-Port-Of: odoo/enterprise#113149
This update resolves an issue where self-billing invoices were incorrectly processed as standard invoices, impacting Peppol compliance. The fix ensures the correct document type ('credit_note') is used when generating UBL invoices for self-billing transactions, improving accuracy and adherence to PEPPOL standards. A demo setup has also been added for testing.
Original PR description
To reproduce: - Activate Peppol - Activate selfbilling on your purchase journal - Create a Vendor Refund - Generate the UBL => The InvoiceTypeCode is 389, meaning it's considered a selfbilling invoice, not a selfbilling credit note. The issue is that we never put the document type of credit_note for selfbilling documents as it wasn't expected. invoice was, due to a else encompassing invoices and bills. Also add a handle demo to be able to create selfbilling documents in demo mode. opw-6132226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263128 Forward-Port-Of: odoo/odoo#260941
This update resolves an error that occurred when posting journal entries using accounts shared between companies during an open audit period. The fix prevents AccessErrors by ensuring users have the correct permissions to access audit status information, allowing for consistent reporting across all companies.
Original PR description
Posting a journal entry using an account shared between multiple companies during an open audit period raises an AccessError. Steps to reproduce: - Configure an account to be shared between Company A and Company B. - Add Company A and Company B in 'Companies' - In the mapping tab, add a code for each company - In Company A, create a tax audit for a specific fiscal period. - Switch to Company B and keep just Company B selected. - Create and post a journal entry using the shared account within the same date period. Issue: An AccessError is raised when posting the move. The system attempts to check the status of the audit records linked to the shared account, to which the user in Company B does not have read access. opw-5993450 Forward-Port-Of: odoo/enterprise#115454
This update resolves an error that occurred when calculating overtime deductions for employees with specific filing statuses (other than 'single' or 'jointly'). The fix ensures the system correctly handles a wider range of employee statuses, preventing unexpected crashes. It also includes minor improvements to testing.
Original PR description
Issue: ---------------------------------------- When having an employee with `l10n_us_filing_status` not in `['single', 'jointly']` and evaluating the rule parameter…
Issue: ---------------------------------------- When having an employee with `l10n_us_filing_status` not in `['single', 'jointly']` and evaluating the rule parameter `l10n_us_qualified_overtime_deduction_cap` an error occurs. Cause: ---------------------------------------- `l10n_us_filing_status` can have 5 values: `['single', 'jointly', 'separately', 'head', 'survivor']` But only `['single', 'jointly']` are defined for `l10n_us_qualified_overtime_deduction_cap` ([src](https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/l10n_us_hr_payroll/data/hr_rule_parameters_data.xml#L48)). When running the rule "Qualified Overtime", the custom Python crashes because we read a key that is not there: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/l10n_us_hr_payroll/data/hr_salary_rule_data.xml#L56 Solution: ---------------------------------------- In the custom Python condition, we first check if the key is there. The custom Python computation also tries to read the key, but it is run only if the condition is validated. So we don't need to change it. Also fixed indentation of test 069. opw-6129657 Forward-Port-Of: odoo/enterprise#115754
This update fixes an issue where the total row in the Planning Gantt view wasn't displaying accurate working hours data when the view wasn't grouped by resources. The change ensures that all working hour information is correctly calculated and displayed, regardless of grouping settings, improving planning accuracy.
Original PR description
Issue: ---------------------------------------- In the Planning Gantt view when we don't group by resources, the total row is not considering the working hours. Steps to reproduce:…
Issue: ---------------------------------------- In the Planning Gantt view when we don't group by resources, the total row is not considering the working hours. Steps to reproduce: ---------------------------------------- - Open Planning - Remove the default group by resources - Have at least a planning slot for a non-flexible employee - The total row doesn't take the working schedule into account Cause: ---------------------------------------- Since [an improvement,](https://github.com/odoo/enterprise/commit/cc35e1a4729453e4f788034a94402ab048eadfcb) the working hours data in given to the `PlanningGanttRenderer` through the progress bars data. This is an issue because the progress bars are only there if we group by resources. ([src](https://github.com/odoo/enterprise/blob/423ab064847dd41d36778a812390e3bec53ba4dc/planning/models/planning_slot.py#L2669-L2678)) Solution: ---------------------------------------- In this commit we partially revert the commit adding the working intervals in the progress bars. Instead of doing it in `_gantt_progress_bar_resource_id()` we create a new method `_get_gantt_planning_data()` which is called directly in `get_gantt_data()` and returns useful information even when there are no progress bars. opw-5507063 Forward-Port-Of: odoo/enterprise#112522
This update resolves an issue where the automatic checkout feature would fail when an employee had multiple overtime entries on the same day, particularly when one entry lacked a defined checkout time. The fix ensures accurate calculation of overtime durations, preventing validation errors and ensuring correct checkout times are applied.
Original PR description
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action…
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action `Attendance: Automatically check-out employees`, an error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Reproduction Steps 1. Create an employee. Set their timezone to UTC and the Overtime Ruleset to Default Ruleset in the settings tab. In the Payroll tab, set a contract start date. 2. Set their Working Hours to a fixed 40 hours/week. Set the timezone of the Working Schedule to UTC. 3. Go to attendances and create 2 attendances on a Sunday: one from 06:00 to 06:01 and a second that starts at 06:02 but that doesn't have a checkout date. 4. Go to Settings and enable Automatic Checkout. Leave the Tolerance to 2 hours. 5. Enable debug mode and go to Scheduled Actions. Look for `Attendance: Automatically check-out employees` and run it manually. ### Expected behavior As the tolerance is 2 hours, the second attendance check-out time should be set at 08:01. ### Unexpected behavior An error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Origin of the issue We retrieve overtime intervals with the domain: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_version.py#L34-L42 This will make us retrieve all the overtimes for a given day, even if overtimes belong to different attendances. However, this means that we will retrieve several times the same overtimes, as this piece of code is executed in this context: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L35 https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L43 This results in the generation of intervals containing multiple times the same overtimes. We then sum their duration to later create work entries: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L47 As we try to create a work entry with too much overtime, that exceeds 24 hours, it raises a validation error. Moreover, as the overtime hours are always stored in UTC, it makes sense to always keep the timezone as UTC when performing a `_read_group` . __ opw-6036064 Forward-Port-Of: odoo/enterprise#116194
This update fixes an issue where products added to a sales order catalog were appearing in the wrong order. The fix ensures products are added to the catalog in the intended sequence, improving the user experience when managing product selections for sales orders. This resolves a bug related to how new order lines are added to the catalog.
Original PR description
# How to reproduce
- Create product n1 & n2
- Create a SO
- Add a section to that SO
- Go to the catalog
- Ensure the section is selected, then add product n1 followed by n2
# The problem
The orders of the product are reversed. n2 is before n1 in the SO
# Cause
Clicking on the Add button will trigger an RPC call to "/product/catalog/update_order_line_info"
that will endup adding a new sale order line :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/sale/models/sale_order.py#L2222-L2227
To determine the sequence of this new order line, we call `_get_new_line_sequence`.
Since a section_id is given, the new order line is inserted right after, before any
product under the same section :
https://github.com/odoo/odoo/blob/c7f05ae216de64d1f8e76e332bc6dd9cf11ce657/addons/account/models/product_catalog_mixin.py#L59-L63
opw-6175704
Forward-Port-Of: odoo/odoo#262556A bug causing spreadsheet image inserts to fail due to excessive data loading has been resolved. The fix bypasses a security check within the database, allowing for more efficient attachment retrieval and preventing memory-related crashes. This ensures stable image insertion, especially in spreadsheets with many attachments.
Original PR description
To reproduce: ============= - In a db with a large amount of attachments - Insert an image in a spreadsheet - Observe the request hanging then ending with an error Problem: ======== - `ir.attachment._search` is overridden to apply security rules by building a domain based on public, `res_model`, `res_id` and `create_uid` fields - When no `res_model` restriction is present, the fallback path ORs in `res_model != False`, which matches nearly every attachment in the database - All matching records are then loaded into memory for Python-side access filtering via `_filtered_access`, causing the request to time out and crash with a memory error Solution: ========= - Set `bypass_search_access=True` on the many2many field definition so the ORM skips the `_search` override and relies on the SQL join to restrict returned records opw-6152979
This update fixes an issue where quiz answers weren't updating correctly after saving. Previously, a full page reload was needed to see the changes. The fix restores a key field to ensure the web client accurately reflects updated answer data, improving the quiz experience.
Original PR description
After adding new answers or editing existing ones in a quiz question and clicking 'Save & Close', the question overview displays incorrect data. New answers appear as empty tags, and modified answers continue to show their old values. The correct data only appears after a full page reload. This regression was introduced in commit 8ceea093, where invisible fields were removed during code cleanup. The `display_name` field is required in the `answer_ids` list view for the web client to correctly update its local cache. Without this field, the client cannot refresh the display names of the tags immediately after modification. This commit restores the `display_name` field as `column_invisible` in the `slide.question` form view. Task-5449335
This update ensures that right-clicking on links within email messages displays the standard browser context menu, rather than the previous message actions. Previously, a technical issue within Odoo's email display prevented this functionality. This change improves the user experience by aligning with expected browser behavior.
Original PR description
Before this commit, when right-clicking on a link in a message of type email, this shows the message actions rather than the browser context menu. We expect to display the browser context menu, as…
Before this commit, when right-clicking on a link in a message of type email, this shows the message actions rather than the browser context menu. We expect to display the browser context menu, as there are many handful feature of browser context menu for links. This was handled in earlier fixes [1][2], but these fixes were not working with messages of type email. This didn't work because messages of type email are inside a shadow DOM, so `ev.target` is necessarily the shadow root and not the specific targeted element. This commit fixes the issue by using `ev.composedPath()` to pick the 1st element, so that this exposes the inner-most element inside the shadow DOM that has been right-clicked. This lets us ignore the showing of message actions in right-click when this comes from a link. opw-6110949 [1]: https://github.com/odoo/odoo/pull/244252 [2]: https://github.com/odoo/odoo/pull/258681 Before / After <img width="441" height="243" alt="before" src="https://github.com/user-attachments/assets/f274e8d2-66af-442e-9a31-27ea1ce4d9bd" /> <img width="605" height="513" alt="after" src="https://github.com/user-attachments/assets/3e241e83-93d0-47e6-970c-b5e5f339417d" />
This update provides pre-configured Italian accounting data to simplify testing and demonstrations of the Odoo Italian localization. The data includes sample partners, bank accounts, invoices, and bills, along with necessary e-invoicing fields, ensuring accurate representation during localization validation.
Original PR description
Purpose: Load a pre-configured set of Italian accounting sample data to facilitate localization testing and demonstrations. Specifications: This commit introduces comprehensive sample data for the Italian localization, configuring the following: * Partners * Bank Accounts * Invoices & Bills * Dynamic Dates: All generated moves use a relative date format to ensure testing data remains relevant and doesn't expire on runbot. * EDI Data: Populates necessary e-invoicing fields (`l10n_it_codice_fiscale`, `l10n_it_pa_index`) for the created partners. task-6103257 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures that website product searches accurately reflect the company a user is logged into. Previously, users could see products restricted to a different company, leading to potential issues with sales orders. The change enforces the website's company setting during searches, resolving this inconsistency.
Original PR description
# Setup Have 2 companies : A & B # How to reproduce - Set your website's company to Company B - Create product X : - Company : Company A - Published - Name : xyz - Go to Users > Any User > Acces…
# Setup
Have 2 companies : A & B
# How to reproduce
- Set your website's company to Company B
- Create product X :
- Company : Company A
- Published
- Name : xyz
- Go to Users > Any User > Acces Rights > Allowed Companies => leave only Company A
- Connect as that user on the website
- Go to the Shop tab and search xyz
# The problem
The product X is displayed, even though we currently use the company B's website and the product is limited to company A.
This causes problem later when Sales Order are created using that product.
If you set the Allowed Companies of the user to both Company A and Company B, then the product is correctly hidden
# Why
When you search something in the search bar, the server does a `_search_with_fuzzy()` that ends up calling a simple `model.search()`.
In our case, this search should not return product X because there is an `ir.rule` that hides product not in the current company :
https://github.com/odoo/odoo/blob/0bb5ac6c1a87367c1ebb343ad6e6e6e56188cf13/addons/product/security/product_security.xml#L34-L38
But the `website` module has some particular rule about setting the current company :
https://github.com/odoo/odoo/blob/0bb5ac6c1a87367c1ebb343ad6e6e6e56188cf13/addons/website/models/ir_http.py#L249-L261
So, in our case, since the user does not have company B in its allowed companies, then
`allowed_company_ids` = Company A. So `('company_id', 'parent_of', company_ids)` is trucy and the product is displayed
# Proposed solution
Doing the search with `with_company` raise an AccessError because the company is not present in the allowed_companies. Chaging the allowed companies logic seems risky because it
may lead to unintended side effects.
We instead enforce the website's company in the search's domain
opw-6115647
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#262366
Forward-Port-Of: odoo/odoo#260138This update corrects a problem where applicants signing an offer multiple times would sometimes be redirected to an outdated contract version. The fix prioritizes active contract versions during the 'Signed Contract' button click, ensuring users always access the correct, current agreement. This improves the applicant experience and data accuracy.
Original PR description
Steps to reproduce: 1- Create an offer for an applicant 2- Sign the offer as an applicant multiple times 3- Counter sign only one of them 4- Click on the "Signed Contract" smart button Issue: In some cases, the smart button will redirect to an archived version. Cause: The search for the version allows for archived versions and has a limit of 1, so sometimes that 1 version turns out to be one of the signed contracts that weren't counter signed. Fix: Add a sort to the search to prioritize active versions. Task-6144381 Forward-Port-Of: odoo/enterprise#115505
This update resolves an issue where the knowledge article's table of contents would incorrectly display the TOC of the last previewed article. The fix ensures the TOC accurately reflects the current article, improving the user experience when creating and editing knowledge content. This prevents confusion and ensures consistent navigation.
Original PR description
### Steps to reproduce 1. Open knowledge 2. Create a new empty article 3. Click on Templates 4. Close the modal ------> Current article's side panel TOC shows the TOC of the previewed article. ### Technical The side panel's TOC is managed by the TOC service. When opening/updating any article, the side panel's TOC is updated according to the current article. When the article picker is previewing the article using the `HtmlViewer`, it also updates the side panel's TOC using the previewed article. Then if we close the dialog without loading the article, the side panel's TOC doesn't get updated. Therefore, opening the side panel's TOC shows the last previewed article's TOC. After this commit, we add a cleanup inside the `HtmlViewer` and the `KnowledgeTableOfContent` to restore the previous TOC manager when it is destroyed. Task-6186675
This update fixes a minor issue where the 'Plan' button appeared in the Gantt view even when there were no Sales Order Lines to plan. The fix ensures the button only appears when there's a valid SOL available, streamlining the user experience and preventing unnecessary dialogue opening. This improves efficiency and reduces potential user confusion.
Original PR description
Steps to reproduce: === - Go to Planning → Gantt view. - Click on an empty cell where no Sale Order Line (SOL) exists. - Observe that the Plan button appears in the multi-selection toolbar. Issue: === The Plan button is shown even when there are no SOL to plan, and clicking it opens the planning form dialogue, which should not happen in this scenario. Cause: === The visibility of the Plan button relies solely on whether `onPlan` is defined. There is no built-in validation to check whether any SOL actually exists for the selected cell before exposing the 'onPlan' action. Fix: === Introduce a new reactive prop `hasAvailableSOL` and compute it before `onPlan` is used. The Plan button is now shown only when an SOL actually exists. task- 5163638
This update resolves a bug that caused Purchase Orders to fail when the quantity ordered was less than the vendor's minimum quantity requirement. The fix ensures a valid supplier is always selected, preventing crashes and allowing for accurate price calculations, even with small order volumes.
Original PR description
FIX] purchase_stock: handle missing seller during PO line update (min_qty) **Steps to Reproduce:** - Install Sale, Inventory, Manufacturing, and Purchase. - Enable MTO, Units of Measure, and Routes.…
FIX] purchase_stock: handle missing seller during PO line update (min_qty)
**Steps to Reproduce:**
- Install Sale, Inventory, Manufacturing, and Purchase.
- Enable MTO, Units of Measure, and Routes.
- Create a product:
Set a vendor price with min_qty = 1.0.
Enable MTO route.
Add a BoM with a component product.
Set quantity to 0.1 (less than vendor min_qty).
- Create a Sale Order with the same product added twice.
- Confirm the Sale Order.
**Issue:**
During procurement:
- First procurement correctly fetches the supplier.
- On PO line update (_update_purchase_order_line), seller is recomputed.
Due to min_qty filtering, no seller is returned when quantity is low.
This results in: Missing seller, Missing product_uom, Invalid price
computation, And finally causes a crash when confirming the Purchase Order,
in _get_stock_move_price_unit: ZeroDivisionErroR
Root Cause:
- _select_seller filters suppliers using min_qty.
During merge/update flow, recomputed quantity may not satisfy min_qty.
Existing valid supplier (from initial procurement) is ignored.
No fallback handling in _update_purchase_order_line.
**Solution:**
- Add fallback logic when _select_seller returns no result: Use
_prepare_sellers() to fetch a valid supplier ignoring min_qty.
- Ensure a supplier is always available for: UoM resolution, Price computation
Prevents crash and ensures consistent PO line updates.
**Result:**
- No traceback when quantity < vendor min_qty
Supplier, UoM, and price are properly set
**OPW-6106487**
Forward-Port-Of: odoo/odoo#259894This update resolves an issue where newly created analytic distribution records would disappear after a page reload. The fix ensures the widget's changes are properly saved to the database, preventing data loss when updating distribution models. This improves data integrity and reliability for users managing analytic accounts.
Original PR description
Steps to reproduce 1. Go to Accounting → Configuration → Analytic Distribution Models 2. Create a new model, name it, and in the distribution column pick an analytic account 3. Click outside the row…
Steps to reproduce 1. Go to Accounting → Configuration → Analytic Distribution Models 2. Create a new model, name it, and in the distribution column pick an analytic account 3. Click outside the row and reload the page Issue The newly created record vanishes because `web_save` received `analytic_distribution: false`. The single click that closes the popover also triggers the editable list's `leaveEditMode`, which calls `record.save()`. That save runs before the widget has flushed the user's pick into `record.data`, so the write goes out with stale/empty data. This became reliably reproducible after [37d78a47bb20], which moved the list renderer's outside-click listener from `document` (bubble) to `window` (capture). Because the list is mounted before the widget, its capture-phase listener now fires first: `leaveEditMode` → `record.save()` is already in flight by the time the widget's own window click handler runs, so the widget's commit loses the race. Solution `record.save()` awaits `_askChanges()` before writing: https://github.com/odoo/odoo/blob/cdf8aaec82ee387c8f29b8327efbc95fd17e2cb8/addons/web/static/src/model/relational_model/record.js#L268-L271 `_askChanges()` triggers `NEED_LOCAL_CHANGES` on the model bus and awaits any proms handlers push onto it: https://github.com/odoo/odoo/blob/cdf8aaec82ee387c8f29b8327efbc95fd17e2cb8/addons/web/static/src/model/relational_model/relational_model.js#L249-L253 This is the framework's standard hook for widgets that hold uncommitted local state; `ace_field` and `domain_field` already use it. Subscribe the analytic distribution widget to the same event and, when the dropdown is open, push a `commitChanges()` prom that awaits the existing `save()`. Because `record.save()` awaits these proms before running `_save`, the widget's pending distribution is guaranteed to be on `record.data` by the time the write payload is built, regardless of click-listener ordering. opw-6106309
3 changes
Resolved issues and error corrections
This update fixes an issue where users were incorrectly directed to a standard form view when opening documents linked through a Studio-added Many2One field. Now, users can directly access the document's Kanban or List view, allowing them to preview and navigate the document content as intended. This enhances usability for document management.
Original PR description
Problem: When opening a linked `documents.document` record from a Many2One field added via Studio, the user is redirected to the standard form view. This is problematic because the form view does not allow the user to preview the actual document or navigate into it if the record is a folder. Solution: override `get_formview_action` to open the Kanban/List/Activity views. task-6068437 Forward-Port-Of: odoo/enterprise#116425 Forward-Port-Of: odoo/enterprise#113149
This update resolves an issue preventing the POS scale integration to work correctly with the latest IoT box version. The IoT box now sends data differently, and this fix adjusts the system to handle the new response format. This ensures accurate weight readings are processed within the POS system.
Original PR description
Steps to reproduce - Use a localisation other than a european one (l10n_eu_iot_scale_cert must not be installed) - Setup the scale for the POS - Open the POS - Add a product to be weighted by scale to the order - Sell one of the weighted product Error: value.toFixed is not a function Cause: New versions of the IoT box send response status via data.status instead of data.status.status. [opw-6121011](https://www.odoo.com/odoo/project/49/tasks/6121011) Forward-Port-Of: odoo/enterprise#116579
This update fixes an error in how VAT reimbursement moves are calculated when carrying over unclaimed tax amounts. The previous calculation incorrectly used data from the previous month's tax report, leading to inaccurate reimbursement amounts. This ensures correct VAT reimbursement processing for June VAT returns.
Original PR description
When generating a VAT return with an unclaimed tax amount carried to the next month, the carryover reimbursement move amounts are computed with an incorrect ratio. Steps to reproduce: - Create and…
When generating a VAT return with an unclaimed tax amount carried to the next month, the carryover reimbursement move amounts are computed with an incorrect ratio. Steps to reproduce: - Create and post a bill in May containing a VAT amount. - Create and post a bill in June containing a VAT amount. - Create a VAT return for May to carry over the VAT amount to the next month. - Create a VAT return for June, requesting the full VAT amount to be reimbursed. - Validate and send the June VAT return. - Check the generated reimbursement move Issue: Line values does not correspond to anything real/tangible. It occurs because when computing the ratio for the move we check the last tax report entry, where we find the amount of tax from the past months and a line balancing the last month that should not be taken into account. The "Balance tax current account (receivable)" line from the tax closing entry is mistakenly picked up as a tax carried forward line, throwing off the amounts. opw-5961836 Forward-Port-Of: odoo/enterprise#116187 Forward-Port-Of: odoo/enterprise#115451
5 changes
Resolved issues and error corrections
This update resolves an issue where the composer field in the portal chatter wouldn't automatically focus after an emoji was added. The fix ensures the composer always receives focus, improving the user experience. This was caused by a missing default value for the composer's autofocus property.
Original PR description
Before this commit, after adding an emoji via the emoji picker in the portal chatter, the composer would not be focused. This is due to the `autofocus` prop of the composer being optional and not having a default value, leading to `NaN` when being incremented while `undefined`. This commit fixes the issue by giving it a default value of 0. task-6204911 Forward-Port-Of: odoo/odoo#263494
This update ensures that delivery orders are created correctly when sales orders are cancelled and then settled through the Point of Sale (PoS) system. Previously, products marked as 'delivered' on the original sales order remained so even after settlement, leading to inaccurate inventory tracking. This fix now generates the necessary delivery orders, resolving this discrepancy.
Original PR description
Steps to reproduce ------------------ 1. Create a sale order with 2 products, confirm it 2. Cancel the SO, then click "Set to Quotation" 3. Open PoS, settle the order and pay 4. Check the delivery…
Steps to reproduce ------------------ 1. Create a sale order with 2 products, confirm it 2. Cancel the SO, then click "Set to Quotation" 3. Open PoS, settle the order and pay 4. Check the delivery order linked to the PoS order The delivery is empty, yet the products still show as "delivered" on the sale order. Why it's happening ------------------ When the SO is cancelled, its moves go to 'cancel' state. After resetting to quotation, those moves stay cancelled. When PoS creates the delivery, the filter in `_create_move_from_pos_order_lines` checks `has_valued_move_ids()` which returns False (all moves are cancelled), and `not move_ids` is also False (cancelled moves still exist). So the lines coming from the SO are excluded from the delivery. The fix ------- We now also create deliveries for lines whose SO moves are all cancelled. These are lines coming from a cancelled SO that now need to be shipped after we have settled their order from PoS. Note ---- The commit c0f338711f028088c98ea459f27c1669b29738d7 fixes this starting from saas-18.2, by introducing a separate `pos_repair` module which simplifies the main `pos_sale` code. In 18.2+, only the test will be forward ported. opw-6055856 Forward-Port-Of: odoo/odoo#263369 Forward-Port-Of: odoo/odoo#256693
This update resolves an issue preventing the POS scale integration from working correctly with the latest IoT box version. The IoT box is now sending data differently, and this fix adjusts the system to handle the new response format. This ensures accurate weight readings for products sold through the POS scale.
Original PR description
Steps to reproduce - Use a localisation other than a european one (l10n_eu_iot_scale_cert must not be installed) - Setup the scale for the POS - Open the POS - Add a product to be weighted by scale to the order - Sell one of the weighted product Error: value.toFixed is not a function Cause: New versions of the IoT box send response status via data.status instead of data.status.status. [opw-6121011](https://www.odoo.com/odoo/project/49/tasks/6121011) Forward-Port-Of: odoo/enterprise#116579
The 'Waiting for Me' filter in the Sign app was incorrectly displaying all documents instead of filtering those requiring the current user's signature. This update fixes a bug caused by an ORM optimization, ensuring the filter accurately shows only relevant documents for users. This improves the user experience and prevents unnecessary document loading.
Original PR description
When applying the 'Waiting for me' filter in the Sign app, all documents are fetched instead of filtering out documents that do not need the current user's signature. Steps to reproduce: 1) Install…
When applying the 'Waiting for me' filter in the Sign app, all documents are fetched instead of filtering out documents that do not need the current user's signature.
Steps to reproduce:
1) Install sign with demo data
2) Open sign app and remove default filter
3) Add a filter Waiting for me
Observed Behavior:
All the documents are fetched.
Expected Behavior:
Documents should be filtered out to only show those where the current user is a signer.
Root Cause:
Since [commit](https://github.com/odoo/enterprise/pull/76079/changes/8b5048f63f91a38a710b611d17f5cf27fbd0a18a), The `_search_need_my_signature` method returned `NotImplemented` for any operator other than `in` at [1]. While the filter uses `=` at [2]. Following a recent ORM optimization with the mentioned commit, the operators are now standardized as shown
From:
`('need_my_signature', '=', True)]`
To:
`[('need_my_signature', 'in', [True])]`
This means the search method now receives the expected `in` operator. However, the return logic uses a `not in` condition when filtering documents waiting for signature.
As a result, instead of filtering documents, all documents are returned.
[1]- https://github.com/odoo/enterprise/blob/012b42c20b48e8e36298875e3291936e68e72375/sign/models/sign_request.py#L107-L108
[2]- https://github.com/odoo/enterprise/blob/012b42c20b48e8e36298875e3291936e68e72375/sign/views/sign_request_views.xml#L177
Fix:
Corrected the return domain logic to fetch the correct documents.
opw-6026935This change resolves a test failure in the MRP module related to multi-lot consumption. The test was failing because the user account lacked the necessary 'lot tracking' group. By explicitly granting this group in the test setup, the expected 'lot_id' field is now correctly displayed, ensuring the test passes.
Original PR description
The test uses the stock move line detailed operations form and expects the `lot_id` field to be present in the view. Without demo data, the current user may not belong to the `stock.group_production_lot` group, causing the field to be absent from the rendered form view and the test to fail. Causing: `AssertionError: 'lot_id' was not found in the view` in line: https://github.com/odoo/odoo/blob/0442c66d26b0c23313f17c566b16e34e7b22c2b6/addons/mrp/tests/test_consume_component.py#L477 Grant the lot tracking group explicitly in the test setup. runbot-243588
9 changes
Resolved issues and error corrections
This update corrects a UI issue where the `l10n_co_edi_ubl` field in the Units of Measure form lacked a label, causing user confusion. The fix ensures the field is clearly identified, improving form clarity and usability for users working with CO Company settings.
Original PR description
Currently, the field `l10n_co_edi_ubl` is displayed without a label in the UoM form, confusing users. **Steps to reproduce:** - Install the `l10n_co_edi` module and switch to the CO Company. -…
Currently, the field `l10n_co_edi_ubl` is displayed without a label in the UoM form, confusing users. **Steps to reproduce:** - Install the `l10n_co_edi` module and switch to the CO Company. - Navigate to Invoicing > Settings. - Enable `Units of Measure & Packagings`. - Open `Units & Packagings` and click `New`. **Observation:** The `l10n_co_edi_ubl` field appears between the `Quantity` label and its corresponding field, but its own label is not visible. <img width="1905" height="324" alt="6180769_before" src="https://github.com/user-attachments/assets/f35c345a-f449-46e4-ad15-6981109fca7a" /> **Root Cause:** The inherited view [1] inserts the field `l10n_co_edi_ubl` before `relative_factor` in the base view [2]. In the base view, `relative_factor` is wrapped inside a `<div>` with a shared label (`Quantity`). Since the new field is inserted inside this structure, it inherits the same layout without having its own label, resulting in the label being hidden. **Fix:** This commit updates the view to ensure that the field `l10n_co_edi_ubl` is properly displayed with its own label, avoiding UI confusion and improving form clarity. **After:** <img width="1907" height="376" alt="6180769_after" src="https://github.com/user-attachments/assets/f96470d3-8df2-4ca4-acf8-f6511a49d725" /> [1]: https://github.com/odoo/enterprise/blob/7b0d07bce92fb4b2cb588344fb0f6e3dd5d94f4a/l10n_co_edi/views/product_uom_views.xml#L4-L13 [2]: https://github.com/odoo/odoo/blob/bae4fa4e0dde2d2e2e4fcdbb968f630c080af818/addons/uom/views/uom_uom_views.xml#L15-L34 opw-6180769
This update adjusts the NSSF (National Social Security Fund) payroll deductions. Now, employees 60 years or older will no longer be subject to these deductions, aligning with Kenyan regulations. The change takes effect the following month after the employee's 60th birthday.
Original PR description
[IMP] l10n_ke_payroll: stop NSSF deductions after 60
When the user is creating a payslip and if the age of employee is >=60 the NSSF deductions must stop
(If the 60 years is finished in 10th of March -> it will stop in April (deduction stop starts from next month))
Test:
Unit test is written to check stopping NSSF deductions with dynamic birthday.
task - 6074658
Forward-Port-Of: odoo/enterprise#115236This update resolves an issue where the 'Add a line' button was unresponsive at the top of mobile grid views (like Timesheets). The fix adjusts how elements are sized on smaller screens, ensuring the button is always clickable. This improves the user experience for mobile users accessing grid data.
Original PR description
**Steps to reproduce** On mobile: - Open a grid view (e.g. Timesheets > All timesheets) - Try to click on "Add a line" for the first employee - Issue: nothing happens. Notice that by scrolling down the list to employees at the bottom, it becomes possible to click on "Add a line". **Cause** `o_grid_cell_overlay` elements (with `h-100`) were taking more than the expected height in mobile, because the `o_grid_section_title` divs only have `position: sticky` on larger viewports. With the default `position: static`, the child element's height was exceeding its parent's height. opw-5853489 Forward-Port-Of: odoo/enterprise#113400
This update fixes a bug where importing a product with a changed subscription type could bypass a necessary warning. Previously, the system would process the import without alerting the user that they were modifying a product already sold as a subscription. Now, a warning is raised to prevent accidental changes to subscription products after they've been sold.
Original PR description
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription…
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription type of the product, the import is executed without issue. However, this leads to undesired behavior: when we go to the product page and try to manually change the subscription type (set it back to subscription), the change is not applied as a warning is raised. ## Reproduction Steps Make sure you have debug mode enabled. 1. Create a product, and check the Subscription box. 2. Click on Orders and create a Quotation with this product, then confirm. 3. Go to Products > Products. Select the list view and search for the product you just created. Select it, and click Actions > Export. 4. Check the import compatible field. Select the fields to export: name, id and recurring_invoice. Upon exporting, a file is downloaded. 5. Access that file and change the recurring_invoice to FAUX or FALSE if your computer is in English. Save the changes. 6. Unselect the product and click on the cog, top right > Import. Click on Upload Data File and select the file that you have downloaded upon exporting, then import. ### Expected behavior A user warning is raised: we shouldn't be able to change the subscription type of the product when it has already been sold. ### Unexpected behavior The import is processed normally. Then, when we access the product page, and try to check the Subscriptions box again, a warning is raised. ## Origin of the issue Nothing prevents the import from occurring in that case. __ opw-6143789 Forward-Port-Of: odoo/enterprise#115046
This update resolves an issue preventing the POS scale integration with the new 19.2 IoT Box. The IoT box is sending data differently, causing a technical error. This fix ensures the scale functionality continues to work correctly for all users.
Original PR description
Steps to reproduce - Use a localisation other than a european one (l10n_eu_iot_scale_cert must not be installed) - Setup the scale for the POS - Open the POS - Add a product to be weighted by scale to the order - Sell one of the weighted product Error: value.toFixed is not a function Cause: New versions of the IoT box send response status via data.status instead of data.status.status. [opw-6121011](https://www.odoo.com/odoo/project/49/tasks/6121011) Forward-Port-Of: odoo/enterprise#116579
This update resolves a test failure related to importing partner and bank account data for Italian reporting. The team restored a previous test data state, ensuring the tests now pass correctly. This prevents disruptions to the Italian reporting functionality.
Original PR description
The related PR brings a data change in a test file that is used here. We bring back the state of that data in the test class, so that the tests don't fail anymore. Community PR: odoo/odoo#254505 Task [link](https://www.odoo.com/odoo/project.task/6046189) task-6046189 Forward-Port-Of: odoo/enterprise#112794
This update fixes an issue where freight charges were incorrectly applied to all pickings, particularly with backorders. The change ensures freight costs are accurately reflected only on the initial, confirmed picking, aligning with how delivery costs should be billed to the customer.
Original PR description
Commit 28b840b introduced logic to include `freight_costs` in the customs document generated bySendcloud. It introduced 2 new issues as a result: 1. When creating backorders, the `freight_costs` are…
Commit 28b840b introduced logic to include `freight_costs` in the customs document generated bySendcloud. It introduced 2 new issues as a result: 1. When creating backorders, the `freight_costs` are not divided but instead propagated to all of the pickings. 2. When there is no SO, we were taking the total value of all delivered goods, which doesn't make much sense considering the `freight_costs` field should be the cost of the delivery itself. Solution ----- For the first problem, there are a couple things to keep in mind: - the total `freight_costs` declared to the customs entity should be the amount invoiced to the customer - products can be added and removed from the picking after the SO has been confirmed - actual delivery cost can change between invoice date and actual delivery date - picking can be split into multiple packages at the user's discretion Considering all of the above, we will simply forward the invoiced amount with the first confirmed picking and none of the backorders. ----- Ticket: opw-6013387 Forward-Port-Of: odoo/enterprise#111304
This update fixes an issue where partners sharing the same VAT number, but with individual turnovers below €250, were incorrectly excluded from VAT reports. The change groups partners by VAT number and includes them in the report if their combined turnover exceeds the threshold, ensuring accurate reporting for Belgian businesses.
Original PR description
When having different partners with the same vat number and their individual turnover values are less than the threshold they were not included in the partner vat listing report even though if the total turnover for their vat number is above the threshold. This commit handles this case by grouping by vat number and if the total turnover for a vat number is above the threshold then it will be shown in the report with another level beneath it to show the partners having this vat number even if their individual turnovers are below the threshold. task-6133010 Forward-Port-Of: odoo/enterprise#115251
This update corrects errors in the Norwegian VAT XML export that were preventing successful validation by Skatteetaten (the Norwegian tax authority). The changes ensure accurate decimal formatting, mathematical calculations, and required legal notes are included, allowing VAT returns to pass government scrutiny. This resolves a critical issue impacting proper tax reporting.
Original PR description
Before commit: The Norwegian VAT XML export fails Skatteetaten validation due to incorrect decimal formatting, mathematical rounding mismatches between base and tax amounts, missing mandatory legal…
Before commit: The Norwegian VAT XML export fails Skatteetaten validation due to incorrect decimal formatting, mathematical rounding mismatches between base and tax amounts, missing mandatory legal notes, and invalid KID number formats. Fix: To strictly follow Skatteetaten validation rules for the Norway VAT XML, the following changes were implemented: - Ensured standard rates drop the decimal (e.g, `25.0` to `25`), and formatted fractional rates like `11.11` to `11,11` in XML. - Rounded down the `tax_amount` to align precisely with government mathematical expectations. - `base_amount` converted into absolute value to ensuring the calculation (`base * rate = tax`) resolves perfectly. - Add the mandatory `<merknad>` explaining the reverse charge method for codes 81, 83, 86, 88, and 91. - Clean the `company_kid` by safely stripping the 'NO' prefix, and 'MVA' suffix. Expect: The generated XML payload now adheres perfectly to Skatteetaten's strict structural and mathematical rules, allowing the VAT return to pass government validations successfully. Related Community PR: https://github.com/odoo/odoo/pull/258390 Task-6033027 Forward-Port-Of: odoo/enterprise#116553 Forward-Port-Of: odoo/enterprise#110792
5 changes
Resolved issues and error corrections
This update ensures Odoo's Czech localization reports accurately comply with Czech tax regulations. Specifically, it implements hybrid rounding for VAT calculations – standard rounding for tax bases and rounding up to the nearest CZK for VAT amounts. This ensures accurate reporting and avoids potential issues with tax authorities.
Original PR description
In the czech localisation there are legal requirements to: - Use standard mathematical rounding for tax bases and subtotals - Round up to the nearest whole CZK for VAT Due/Tax Amounts - Calculated totals must be the sum of the previously rounded lines Which are not implemented in the cuurent report generation, The current change overrides the formula computation for these specific lines to comply with this legal requirement. task: 6081523
This update fixes a previous issue where helpdesk returns weren't available for orders shipped through dropshipping. Now, users can properly return dropshipped transfers directly from the helpdesk ticket, streamlining the returns process and improving customer service. This ensures consistent return functionality regardless of order fulfillment method.
Original PR description
### Steps to Reproduce: - Enable dropshipping in Inventory settings - Create a product with inventory tracking enabled - Enable dropship under the Inventory tab for the product - Add a vendor and…
### Steps to Reproduce: - Enable dropshipping in Inventory settings - Create a product with inventory tracking enabled - Enable dropship under the Inventory tab for the product - Add a vendor and quantity under the Purchase tab - Create a sale order for the product - Go to the Purchase stat button and confirm the order - Click on the Dropship stat button and validate the transfer - Open Helpdesk and create a new ticket for the same partner ### Issue: The "Returns" stat button is not visible for dropshipped deliveries. ### Current behaviour: - The helpdesk ticket allows returns of customer orders only if the order is outgoing. However, this does not cover the usecase where the order was dropshipped and still needs to be returned to the vendor. - With the current behavior, the user needs to find the customer's order to return the transfer as it is not possible to do from the ticket. ### Expected behaviour: Helpdesk tickets should also allow returns of dropshipped transfers (done and linked to the SO). ### Fix: The helpdesk return logic was limited to only 'outgoing' pickings. This commit extends the 'return' button should be visible if there is at least one delivery or dropship order linked to the partner of the ticket Issue:https://github.com/odoo/enterprise/pull/81378 task-4881338 Forward-Port-Of: odoo/enterprise#91402
This update resolves an issue where the automatic checkout feature would fail when an employee had multiple overtime entries on the same day, particularly when one entry lacked a defined checkout time. The fix ensures that the system correctly calculates and applies checkout times, preventing validation errors related to excessive overtime durations.
Original PR description
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action…
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action `Attendance: Automatically check-out employees`, an error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Reproduction Steps 1. Create an employee. Set their timezone to UTC and the Overtime Ruleset to Default Ruleset in the settings tab. In the Payroll tab, set a contract start date. 2. Set their Working Hours to a fixed 40 hours/week. Set the timezone of the Working Schedule to UTC. 3. Go to attendances and create 2 attendances on a Sunday: one from 06:00 to 06:01 and a second that starts at 06:02 but that doesn't have a checkout date. 4. Go to Settings and enable Automatic Checkout. Leave the Tolerance to 2 hours. 5. Enable debug mode and go to Scheduled Actions. Look for `Attendance: Automatically check-out employees` and run it manually. ### Expected behavior As the tolerance is 2 hours, the second attendance check-out time should be set at 08:01. ### Unexpected behavior An error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Origin of the issue We retrieve overtime intervals with the domain: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_version.py#L34-L42 This will make us retrieve all the overtimes for a given day, even if overtimes belong to different attendances. However, this means that we will retrieve several times the same overtimes, as this piece of code is executed in this context: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L35 https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L43 This results in the generation of intervals containing multiple times the same overtimes. We then sum their duration to later create work entries: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L47 As we try to create a work entry with too much overtime, that exceeds 24 hours, it raises a validation error. Moreover, as the overtime hours are always stored in UTC, it makes sense to always keep the timezone as UTC when performing a `_read_group` . __ opw-6036064 Forward-Port-Of: odoo/enterprise#116194
This update resolves a crash issue that occurred when creating point-of-sale orders with the pos_avatax module installed. The fix re-enabled a previous method to correctly identify the customer's shipping information, ensuring order creation proceeds smoothly. This improves stability and prevents disruptions for users.
Original PR description
Before this commit, when pos_avatax was installed, creating a pos order could crash because the pos order does not have the partner_shipping_id field. This commit re-adds the _get_avatax_ship_to_partner method as it was before the refactor https://github.com/odoo/enterprise/commit/0404086db567ee0595414263d36a3b7dceaa0dbe, which returns the partner_id for the pos order. The `_get_avatax_ship_to_partner` is overridden in `pos_avatax`. Since a `pos.order` does not have a `partner_shipping_id`, the overridden function only reads the partner_id. opw-6122280 Forward-Port-Of: odoo/enterprise#116682 Forward-Port-Of: odoo/enterprise#115840
This update addresses a potential instability issue in the HR Payroll module by eliminating a specific coding pattern. This change enhances the overall reliability and stability of payroll processing, reducing the risk of errors. The update was prompted by related discussions and fixes within the Odoo core development team.
Original PR description
See odoo/odoo#260982 See odoo/upgrade#10028 See odoo/upgrade-util#419
10 changes
Resolved issues and error corrections
This update corrects a technical issue where partners with VAT information were incorrectly flagged in the annual VAT listing report. The fix ensures that these partners are no longer displayed in the warning, improving the accuracy and usability of the report for accounting and tax purposes. This resolves a minor reporting discrepancy.
Original PR description
Partners with / in VAT shouldn't be displayed in the warning for the annual VAT listing. task-6081162
This update corrects a bug that prevented the generation of ABA files for payroll payments. Previously, the payment batch needed to be assigned before validation, which caused blank files. This fix ensures both the payment and payslip batches generate consistent ABA files, improving the accuracy of financial reporting.
Original PR description
Payslip batch needs to be assgned before the payment batch is validated, otherwise the ABA file will be blank. This commit ensures that flow and the test ensure both aba flows generate the same file content. task-6123029
This update resolves an error message issue within the WPS wizard for South Africa payroll. The fix removes an obsolete field and clarifies the error message when the debit date is equal to or after the value date, ensuring accurate reporting and a better user experience. This improves the reliability of the WPS process.
Original PR description
This commit fixes the error message displayed to the user when the debit date of the wage payment is greater than or equal to the value date on the WPS wizard. It also hides an unnecessary field `l10n_sa_wps_debit_date` from the wizard, rendering the field obsolete. TaskID-6130969
This update resolves a bug where barcode scanning for products with different packaging units would intermittently assign quantities to the wrong line. The fix ensures accurate quantity updates by correctly matching the packaging uom during the scanning process, preventing alternating line assignments.
Original PR description
Issue ----- When there are 2 lines for a single product and different packaging uoms, scanning a packaging barcode alternates between lines. Steps to reproduce ----- - Enable packagings - Create a…
Issue ----- When there are 2 lines for a single product and different packaging uoms, scanning a packaging barcode alternates between lines. Steps to reproduce ----- - Enable packagings - Create a product AAA - barcode 1 - Create a packaging 6-Pack - 6 units - barcode for AAA set to 6 - Create a PO - one line for 30 units of AAA - one line for 5 6-Pack of AAA - Confirm PO and open picking in barcode - Scan "6" multiple times > Quantity increases on both lines, alternating for each scan Cause ----- Both lines can be found as matching lines when doing https://github.com/odoo/enterprise/blob/d279632db25713dd639a51385cad197dfdbd2bdc/stock_barcode/static/src/models/barcode_model.js#L1426 The reason it alternates between the lines is because we set the currently selected line first in the array - and since both lines match, the `foundLine` returned ends up being the non-selected line. https://github.com/odoo/enterprise/blob/d279632db25713dd639a51385cad197dfdbd2bdc/stock_barcode/static/src/models/barcode_model.js#L1823-L1832 We can avoid this y refining the `break` condition of the loop to also match the packaging uom. ----- Ticket: opw-6034572
This update resolves an issue where the automatic checkout feature would fail when an employee had multiple overtime entries on the same day, particularly when one entry lacked a defined checkout time. The fix addresses a calculation error that resulted in a validation error exceeding the 24-hour overtime limit. This ensures the automatic checkout process functions correctly for employees with complex overtime schedules.
Original PR description
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action…
__ ## Short functional explanation of the error When an employee has multiple overtimes for the same day, including one that doesn't have a check-out date. When running the scheduled action `Attendance: Automatically check-out employees`, an error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Reproduction Steps 1. Create an employee. Set their timezone to UTC and the Overtime Ruleset to Default Ruleset in the settings tab. In the Payroll tab, set a contract start date. 2. Set their Working Hours to a fixed 40 hours/week. Set the timezone of the Working Schedule to UTC. 3. Go to attendances and create 2 attendances on a Sunday: one from 06:00 to 06:01 and a second that starts at 06:02 but that doesn't have a checkout date. 4. Go to Settings and enable Automatic Checkout. Leave the Tolerance to 2 hours. 5. Enable debug mode and go to Scheduled Actions. Look for `Attendance: Automatically check-out employees` and run it manually. ### Expected behavior As the tolerance is 2 hours, the second attendance check-out time should be set at 08:01. ### Unexpected behavior An error occurs: `odoo.exceptions.ValidationError: Duration must be positive and cannot exceed 24 hours.` ## Origin of the issue We retrieve overtime intervals with the domain: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_version.py#L34-L42 This will make us retrieve all the overtimes for a given day, even if overtimes belong to different attendances. However, this means that we will retrieve several times the same overtimes, as this piece of code is executed in this context: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L35 https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L43 This results in the generation of intervals containing multiple times the same overtimes. We then sum their duration to later create work entries: https://github.com/odoo/enterprise/blob/64f813dab727d76286c1ff6c80c08cb6a6737b49/hr_work_entry_attendance/models/hr_attendance.py#L47 As we try to create a work entry with too much overtime, that exceeds 24 hours, it raises a validation error. Moreover, as the overtime hours are always stored in UTC, it makes sense to always keep the timezone as UTC when performing a `_read_group` . __ opw-6036064
This update resolves an issue where scanning pack-in-pack inventory counts wasn't working reliably. The fix ensures that inventory updates accurately reflect the quantity of items within nested packages, improving the accuracy of physical inventory counts. This prevents data discrepancies and ensures correct stock levels.
Original PR description
### Steps to reproduce: - In the settings enable "Packages" - Create a storable product A and put 1 unit in a package P in stock - Inventory > Products > Packages > open your package P - Set a parent…
### Steps to reproduce: - In the settings enable "Packages" - Create a storable product A and put 1 unit in a package P in stock - Inventory > Products > Packages > open your package P - Set a parent package PP as container - Inventory > Operations > Adjustments > Physical Inventory - Select you product line for A > Request a count (from the control panel button) - Enable Show Expected Quantity and confirm - Go to the barcode app > Count Inventory (1) - scan your parent package PP #### > traceback: Uncaught Promise > Cannot create property 'inventory_quantity' on boolean 'false' ### Cause of the issue: When the Package scan is processed, we loop over all quants related to it: https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_quant_model.js#L566-L569 https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_quant_model.js#L602-L617 And for each of these we try to find an existing line representing the quant to update or we do create a new line. Now, the issue, is that the subpackages of the quant are not provided to find the quant candidate line to update. As such, no line is found we enter the else clause and try to createa a NewLine: https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_quant_model.js#L617-L627 This time however, the appropriate subpackage (the one of the quant) is provided to the arguments. And, since the line representing this quant is already existing, the `_createNewLine` will return False: https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_quant_model.js#L393-L399 https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_quant_model.js#L423 This leads to a traceback at the end of the else close since `false.inventory_quantity` doe not make sense (Cannot create property 'inventory_quantity' on boolean 'false') https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_quant_model.js#L626-L627 Fix: We adapt the `_processPackage` of the `BarcodeQuantModel` to mimic the existing 'update' behavior on the `BarcodePickingModel`: https://github.com/odoo/enterprise/blob/30a28e28f8dd27cf2c88df65e5ff47eab59360c7/stock_barcode/static/src/models/barcode_picking_model.js#L2110-L2133 Note that UOM converstion should not be required since quants are already uniformly expressed in the product uom: https://github.com/odoo/odoo/blob/30b4edace6b0859cb1b1ba4f7f2ea80ba5398e3d/addons/stock/models/stock_quant.py#L52-L54 opw-5864591
This update fixes an issue where users were incorrectly directed to a standard form view when opening documents linked through a Many2One field. Now, when a document is opened from this field, users will be taken directly to the Kanban view, allowing them to preview and navigate the document content effectively. This enhances the usability of document management.
Original PR description
Problem: When opening a linked `documents.document` record from a Many2One field added via Studio, the user is redirected to the standard form view. This is problematic because the form view does not allow the user to preview the actual document or navigate into it if the record is a folder. Solution: override `get_formview_action` to open the Kanban/List/Activity views. task-6068437 Forward-Port-Of: odoo/enterprise#116425 Forward-Port-Of: odoo/enterprise#113149
This update fixes an issue where the DMFA report incorrectly displayed '5' for 'Days Per Week' when employees worked fewer than 5 days a week. The fix accurately calculates the number of days based on the employee's actual working schedule, ensuring accurate reporting for Belgian payroll compliance.
Original PR description
## Issue When generating a DMFA report with a working schedule with more or less than 5 days a week, the *Days Per Week* value in the report is still appearing as 5. ## Steps to reproduce 1. Install…
## Issue
When generating a DMFA report with a working schedule with more or less than 5 days a week, the *Days Per Week* value in the report is still appearing as 5.
## Steps to reproduce
1. Install *Belgium - Payroll* (`l10n_be_hr_payroll`)
2. In Payroll's Settings:
- set *ONSS Registration Number* to `0830123456`
- set *DMFA Employer Class* to `083`
- create a *Work Address DMFA code* (any name, any numeral code, but set the *Working Address* to the Belgian company used for the rest of the steps)
3. In Employees' Settings, set the *Company Working Hours* to a new Working Schedule, with 9 hours/day, 4 days/week. E.g from Monday to Thursday included:
- Work from 8:00 to 12:00
- Lunch from 12:00 to 13:00
- Work from 13:00 to 18:00
4. Create an Employee E for the Belgian company:
- In the *Payroll* tab, set the start date of the contract to 01/01/2026.
- In the *Personal* tab, set the *NISS Number* to `85073003328`
5. Create the payslip for January 2026 for the Employee E.
6. In Payroll > Reporting > Belgium > DMFA, create a new DMFA for the first quarter of 2026 and generate the PDF report
7. **In the generated PDF report, the _Days per Week_ line is set to 5.**
## Cause
The number of days was calculated by multiplying `5` with the `work_time_rate` of the related calendar. This is inaccurate in the case of a company where employees are only expected to work 4 days a week.
opw-6103934
Forward-Port-Of: odoo/enterprise#116667
Forward-Port-Of: odoo/enterprise#113804This fix corrects a bug where users could still edit protected folders within the company's main document area. The system now ensures that the document details panel remains read-only when a protected folder is accessed, maintaining data integrity and security. This resolves an issue where permissions were not consistently enforced.
Original PR description
In odoo/enterprise#106192, we have modified the function userPermissionViewOnly that was preventing the user from editing document he cannot: we have removed the condition preventing user to edit…
In odoo/enterprise#106192, we have modified the function userPermissionViewOnly that was preventing the user from editing document he cannot: we have removed the condition preventing user to edit protected document (mainly folder at the company root). That was an error as even if the user has "edit" access (which is ensured in that method), the document can still be protected and the form to edit it should be in readonly then. We ensure here that the form in the details panel is in readonly in that case. How to reproduce: - log as demo and go to Document - Click on Inbox folder - Open details panel - Change for example the contact of the document You get an error while you shouldn't be able to edit it (as the folder is protected). Technical note: we re-add the condition in the method userPermissionViewOnly: (!this.documentService.userIsDocumentManager && this.record.data?.user_folder_id === "COMPANY") that we slightly modify to limit the protected document to folder only: (!this.documentService.userIsDocumentManager && this.record.data?.user_folder_id === "COMPANY" && this.record.data?.type === "folder") Task-5881531
This update resolves an error in the Luxembourg VAT reports (FAIA) caused by a missing required TaxType element ('TVA'). The fix ensures the reports comply with Luxembourg tax regulations, preventing export failures. This was triggered by a customer report and verified against XSD files.
Original PR description
This is one of several commits fixing the FAIA xml export. The customer in ticket [opw-5427296](https://www.odoo.com/odoo/unassigned-tasks/5427296) received several errors which mention that the `TaxType` element should be 'TVA'. This is corroborated by one of these elements in the XSD files for the FAIA report. The XSD files can be found at the link below. https://pfi.public.lu/dam-assets/backup/FAIA/FAIA/XSD_Files.zip opw-6118272 [link](https://www.odoo.com/odoo/project.task/6118272) Forward-Port-Of: odoo/enterprise#115293 Forward-Port-Of: odoo/enterprise#113720
15 changes
Resolved issues and error corrections
This update fixes an issue where manufacturing costs were being double-counted in project profitability reports. The change ensures that only the primary manufacturing orders (source MOs) linked to a project are included in the calculations, providing a more accurate view of project costs. This improves the reliability of financial reporting for manufacturing projects.
Original PR description
Steps to reproduce: ==== - Install the project_mrp_account module. - Enable the 'Routes' and 'Replenish on Order' options in Inventory. - Create products with a multilevel MO. - Create a Sale Order…
Steps to reproduce: ==== - Install the project_mrp_account module. - Enable the 'Routes' and 'Replenish on Order' options in Inventory. - Create products with a multilevel MO. - Create a Sale Order that triggers Manufacturing Orders (MO), then validate it. - Go to the Project Dashboard and check the costs in the profitability section. Issue: ==== - Currently, the system sums the amount of all MOs without differentiating between source and child MOs. This results in double-counting of manufacturing costs in the profitability report. Cause: ==== - In 'account.analytic.line', the domain is only based on 'auto_account_id' and 'category'. There is no relation or differentiation between source and child MOs, so costs are aggregated incorrectly. Fix: ==== - We can filter out all the child MO's by checking out all MO's linked with that specific project. Only these source MOs are considered for cost calculation in the project profitability dashboard, avoiding duplication. Only these source MOs are considered for cost calculation in the project profitability dashboard, avoiding duplication. task-4969489
This update fixes an issue where manufacturing costs were being double-counted in project profitability reports. By removing the project association from child Manufacturing Orders, the system now accurately calculates costs, improving the reliability of project financial reporting. This change was implemented to align with a previous update in version 19.0.
Original PR description
**Steps to reproduce:** Install the project_mrp_account module. Enable the "Routes" and "Replenish on Order" options in Inventory. Create products with a multilevel Manufacturing Order (MO) flow. Create and confirm a Sales Order that triggers Manufacturing Orders, then validate it. **Current behavior:** The system sums the cost of all Manufacturing Orders without distinguishing between source and child MOs. As a result, manufacturing costs are double-counted in the project profitability report. **Fix:** Remove the project from child MOs to avoid double-counting in the project dashboard and MRP analytic stat button. In 19.0, the project is also set on child MOs. https://github.com/odoo/odoo/commit/2713876dbc70d3984e584a9037a2206dcda4e84a task-4969489
This update prevents Odoo from incorrectly importing bank account details for sales invoices, which was causing errors related to company mismatches. The fix now restricts bank import to purchase documents (invoices), ensuring data accuracy and preventing disruptions to the accounting process.
Original PR description
# Description of the issue/feature this PR addresses: A recent change introduced by PR [#242365](https://github.com/odoo/odoo/pull/242365) removed a company guard when importing bank information…
# Description of the issue/feature this PR addresses: A recent change introduced by PR [#242365](https://github.com/odoo/odoo/pull/242365) removed a company guard when importing bank information from EDI documents. As a result, during Factur-X and UBL 2.0 imports, Odoo may attempt to create or link a bank account on the wrong partner, leading to company constraint errors when importing credit notes. This issue primarily affects outbound credit notes, where Odoo incorrectly tries to import the company’s own bank account as a partner bank. <img width="1195" height="915" alt="image" src="https://github.com/user-attachments/assets/b93d9ec4-8840-4e06-87ed-8590cfe9149d" /> # Current behavior before PR: During Factur-X and UBL 2.0 imports: - Bank information extracted from the XML is always passed to _import_partner_bank, regardless of the document type. - For sales documents (out_invoice, out_refund), the bank account in the XML belongs to the company itself. - Odoo then attempts to create or assign this bank account to the partner, triggering an error such as: > Incompatible companies on records: Invoice belongs to company A, bank account belongs to another company. - Vendor invoices (in_invoice) work by chance, but the logic is incorrect and fragile. - The behavior is inconsistent with how Factur-X and UBL define PayeePartyCreditorFinancialAccount (always the seller’s bank). # Desired behavior after PR is merged: Bank details are imported only for purchase documents (in_invoice, in_refund), where the seller is the vendor and importing their bank account is correct. - For sales documents (out_invoice, out_refund), the import of bank details is skipped, avoiding: - Incorrect partner bank creation - Company constraint errors - This behavior is implemented consistently for: Factur-X imports, UBL 2.0 imports The fix uses invoice.is_purchase_document() ensuring: - Vendor bank details continue to be imported correctly - No regression for existing Factur-X vendor invoice flows - Credit note imports behave correctly again Odoo-ticket: [5877901](https://www.odoo.com/my/tasks/5877901) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a bug preventing Odoo invoices with a specific tax category ('O-service out of tax scope') from passing Peppol validation. The fix ensures this category doesn't include VAT IDs, aligning with Peppol requirements. This ensures compliance and proper export of invoices to Peppol networks.
Original PR description
**PROBLEM** In peppol, there is a tax category 'O-service out of tax scope'. This tax category is used when what is invoice can't be tax (out of the tax scope). This is different from tax exemption: when using tax category O, there can't be any vat id on the invoice. This also means you can't use tax category O with other taxes, since other taxes need the vat id. Invoices generated by odoo with tax category O failed peppol validation. **STEP TO REPRODUCE** 1. install account_edi_ubl_cii_tax_extension. 2. Create a tax with tax category O. 3. Create an invoice and try validating using the file validator. 4. You should have error BR-O-02 and BR-O-05. opw-6012669
This update corrects a previous omission by adding the 'l10n_pl_bank_verification' module to the weblate.json file. This ensures that all translations for this new functionality are correctly included in the Odoo system, improving localization for Polish users.
Original PR description
[FIX] Add l10n_pl_bank_verification to weblate.json In a previous PR, we added the new module 'l10n_pl_bank_verification' but didn't added it in weblate.json. This PR fix it See odoo/odoo#262518
This update corrects a minor error in the account_edi_ubl_cii module that was causing an unnecessary conditional check when determining tax exemption reasons for Belgium (BE). This change ensures the system operates correctly and efficiently, improving data processing accuracy. The fix was implemented as a routine maintenance update.
Original PR description
When getting the tax exemption reason for BE, a redundant conditional was added by mistake related task-id-5905176
This update fixes a crash that occurred when creating purchase invoices with vendor bills that only used a description and UoM, without a product assigned. The change ensures purchase matching is more robust and can handle bills identified solely by their description, improving data accuracy and preventing errors during invoice creation.
Original PR description
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to…
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to reproduce the issue: 1. Enable Units of Measure in Settings 2. Create and confirm a Vendor Bill setting a description and a UoM, but leave the Product field empty. 3. Click on "Purchase matching" smart button 4. The system throws a traceback with the error: "The unit of measure Unit defined on the order line doesn't belong to the same category as the unit of measure False defined on the product." ### Cause of the issue: In the purchase.bill.line.match model, the field product_uom_qty was computed by calling _compute_quantity using line.product_uom_id. Since product_uom_id is a related field on product_id.uom_id, it returns False when no product is set. The UoM conversion logic cannot handle a False destination category, leading to the crash. ### Reason to introduce the fix: Make purchase matching robust when imported vendor bills contain lines identified only by their description and not by a product. Note that for `purchase.bill.line.match` corresponding to an account.move.line but not related to any product, the `product_uom_qty` should match the quantity of the `aml_id` instead of attempting a UoM conversion based on a missing product UoM for the behavior to be consistent with the inverse method: https://github.com/odoo/odoo/blob/59d6232979b8499fde6cb700df1870e2e38d0d3e/addons/purchase/models/purchase_bill_line_match.py#L45-L54 opw-5911526 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a bug where users were incorrectly redirected after signing a document. The fix simplifies the redirection process by directing users back to their list of signatures on the portal, eliminating a confusing routing issue. This ensures a smoother user experience when completing and closing signature requests.
Original PR description
steps : - create a signature request with 2 roles, assign those to demo or portal user - create another one with a single signature role assigned to the demo or portal user - go on the portal and click on the second document to sign it - complete the document then click close on the thank you popup -> you are redirected on the portal view of the first document This happens because the redirect to /my/document is made using the sign_request id but the controller is using a sign_request_item id. Instead of adding a confusing controller route to be able to pass sign_request ids to reach the document's portal page, we simply redirect to the list of signatures on the portal instead. opw-6190390
This update resolves a crash that occurred when validating shared POS orders with loyalty discounts. The issue stemmed from how temporary discount IDs were handled during order serialization and validation, leading to a 'TypeError'. The fix ensures accurate loyalty point calculations and stable order validation across different POS configurations.
Original PR description
When a draft POS order saved by another session is loaded in a trusted POS, reward lines with an automatically applied discount cause a traceback. Steps to reproduce: ------------------- * In POS…
When a draft POS order saved by another session is loaded in a trusted POS, reward lines with an automatically applied discount cause a traceback. Steps to reproduce: ------------------- * In POS Settings, enable Trusted POS between two configs * Create an automatically applied discount on a product * In POS 1: add the product, select a customer, save the order for later * In POS 2 (trusted): open the saved order, select a payment method and validate > Observation: TypeError: Cannot read properties of undefined (reading 'id') Why the fix: ------------ When POS 1 serializes the draft order, temporary negative coupon IDs on reward lines are stripped to `undefined` (pos_order_line.js serialize()). When POS 2 loads the order and tries to validate it, several code paths access `.id` directly on `coupon_id` without guarding against `undefined`: Additionally, `updateRewards()` keeps the stale reward line while the auto-claim creates a fresh one, so the order briefly holds two discount lines. The second `orderUpdateLoyaltyPrograms()` then computes loyalty points against both lines, producing a wrong result. Fixed by deleting stale reward lines (coupon_id = undefined) at the start of `updateRewardsMutex.exec()` so the auto-claim creates a single correct line. opw-6049469
This update ensures event tickets are created correctly when selling event tickets in POS while offline. Previously, a page reload would cause the system to lose the event registration data. The fix changes how the system manages local data storage, guaranteeing that event tickets are generated when an offline order is synced with the server.
Original PR description
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open…
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open a POS session with `pos_event` * Sell an event ticket * Switch to offline mode * Validate payment while offline (order becomes paid but unsynced) * Reload/close and reopen POS, then reconnect * Let the order sync > Observation: The `pos.order` is created on the backend, but `event.registration` and `event.registration.answer` are missing so tickets are not generated. Why the fix: ------------ `pos_event` used `order.finalized` as IndexedDB cleanup condition for `event.registration` and `event.registration.answer`. For paid-but-unsynced orders, `finalized` is already true, so those records can be removed from IndexedDB too early. After reload, the order is restored/synced but without its event registration payload. Implementation: --------------- Use `order.canBeRemovedFromIndexedDB` instead of `order.finalized` for `event.registration` and `event.registration.answer` retention rules, so records are kept locally until the order is truly synced (server id assigned) or canceled. Test Note: --------------- Use case is hard to simulate exactly. Add a basic unit test to assert both registration models are kept for paid unsynced orders and only removable once synced. opw-6056079
This update resolves an issue where custom (free text) product attributes weren't correctly displayed in the POS system when settling website orders. The fix ensures that customer-entered text is accurately reflected in the order line, improving the customer experience and order accuracy. It corrects a data retrieval problem within the Odoo POS module.
Original PR description
When a sale order containing a product with a custom (free text) attribute was settled in POS, the order line displayed the placeholder attribute value name (e.g. "Custom") instead of the actual text…
When a sale order containing a product with a custom (free text) attribute was settled in POS, the order line displayed the placeholder attribute value name (e.g. "Custom") instead of the actual text entered by the customer. Steps to reproduce: ------------------- * Create a product with a free text attribute (create_variant='no_variant', is_custom=True) * Go to the website's shop (works best in a new private tab) * Fill the free text attribute and add the product to the cart * Click on checkout * In POS, open Quotation/Order and settle the order > Observation: the order line shows "Custom" instead of the text Why the fix: ------------ `SaleOrderLine._load_pos_data_fields` was not exposing `product_no_variant_attribute_value_ids` nor `product_custom_attribute_value_ids`, so the JS `settleSO` function received no attribute data on the `line` object. As a result, the new POS order line was created with empty `attribute_value_ids` and `custom_attribute_value_ids`, leaving `constructFullProductName` unable to find the custom text. The fix adds both fields to `_load_pos_data_fields` and updates `settleSO` to use them when building the new POS order line. The dynamic fetch path (`_getSaleOrder`) is also updated to explicitly read the `product.attribute.custom.value` records so the data is available for orders loaded at runtime. opw-5958678
This update corrects a bug in the Odoo portal that was preventing certain types of messages from being displayed to users. Previously, only 'internal notes' were hidden, but other non-internal message types were incorrectly excluded. This change ensures all non-internal messages are visible while still hiding internal notes as intended.
Original PR description
*: test_mail_full Since #138233, portal messages were strictly filtered by the `mt_comment` subtype. This was intended to hide internal notes, but it incorrectly excluded other non-internal message subtypes. Basically we want the share domain (`_get_search_domain_share()`) to apply to all users in the portal. This change ensures internal notes remain hidden while allowing all other non-internal non-comment subtypes to be visible. opw-6031571
This update fixes an issue where prepaid tax calculations were inaccurate due to rounding errors. The change ensures correct global rounding is applied during tax calculations for Saudi Arabia, preventing discrepancies in invoice amounts. This improves the accuracy of financial reporting.
Original PR description
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each…
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each with 15% taxes (triggers rounding precision issues) - Create and confirm 100% downpayment invoice - Deliver, then create final invoice with downpayment lines - Call `_l10n_sa_get_prepaid_amount()` on final invoice > Tax amount was calculated as 35.67 instead of correct 35.64 ### Cause of Issue: The prepaid amount calculation was summing pre-rounded `tax_amount_currency` values from individual downpayment lines (4.45 + 4.46 + 4.46... = 35.67), instead of summing unrounded `raw_tax_amount_currency` values (4.455 × 8 = 35.64) to calculate `tax_amount`. https://github.com/odoo/odoo/blob/27930ae41a5f03bd499983109de7f632472c3650/addons/l10n_sa_edi/models/account_edi_xml_ubl_21_zatca.py#L227-L240 This violates Odoo's [recent change](https://github.com/odoo/odoo/pull/180062) in `round_globally` pattern which states: https://github.com/odoo/odoo/blob/8a88756bed194910bc5a47e93f0e29610dbeee1f/addons/account/models/account_tax.py#L2208 ### Fix: Ensure cumulative rounding errors are avoided and correct global rounding is applied. opw-5881564
This update resolves a problem where custom attributes weren't selectable in kiosk mode, causing the attribute heading to appear but not the options. The fix ensures that custom attributes are correctly hidden when a single value is selected, and the 'Add to Cart' button functions properly. This improves the kiosk user experience.
Original PR description
Step to reproduce: - have two attributes A and B - A has only 1 attribute value with is_custom = True - B can have any two value ( ex. gender: male/female) - use it on a product and make it available…
Step to reproduce: - have two attributes A and B - A has only 1 attribute value with is_custom = True - B can have any two value ( ex. gender: male/female) - use it on a product and make it available in POS for kiosk - start kiosk and open that product Observation: - we do not get option to select option from A but the heading is visible - when we select from B, Add to cart is disabled. Cause: - we do not allow attribute values with is_custom = True in kiosk - but we display the attribute regardless - the Add to cart btn depends on `selectedValues`, which requires value from each attribute, in this case, we are not seletion anything from A - so it is disabled Fix: - we introduced `attributesToDisplay` which will hide heading in case of single custom value for any attribute - for Add to cart, wenow do not expect value from `is_custom` attribute values. Before: <img width="1834" height="854" alt="image" src="https://github.com/user-attachments/assets/ae0d6d91-c3b6-47e9-8c08-f55efc6e0a33" /> After: <img width="1830" height="828" alt="image" src="https://github.com/user-attachments/assets/7e2376b6-4704-4039-9db0-0b0bf822c33d" /> opw-6100965 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update addresses a technical issue related to Point of Sale sequences, specifically 'orphaned' sequences created when POS sessions are deleted. Cleaning these sequences prevents exceeding the database's limit of 10,000 sequences, which is crucial for performance on Odoo.sh. This ensures a stable and efficient Point of Sale experience.
Original PR description
The current vacuum only collects `ir_sequence` from closed sessions but doesn't take into account "orphaned" sequences, such as sequences which belongs to `pos.session` that have been deleted. We also need to clean those to avoid having too many Postgres sequences, especially since it's limited to 10K on Odoo.sh. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
4 changes
Resolved issues and error corrections
This update corrects a reporting issue where planned hours weren't correctly excluded on public holiday days. The fix ensures that only public holidays related to the employee's company are considered when generating timesheet forecasts, improving reporting accuracy and preventing over-allocation of time.
Original PR description
## Steps to reproduce: - Install project_timesheet_forecast module - Create a public holiday in one company - In another company create a planning slot for an employee that overlaps with the holiday - Go to Timesheets/Planning analysis report - Notice the report is not showing planned hours for the employee on the day of the public holiday ## Cause: When filtering the resource_calendar_leaves we don't check for the company so any public holiday in any company will be taken into account even if it doesn't affect the employee ## Fix: Exclude holidays that has different company than the planning slot opw-5027070
This update resolves a validation error that occurred when creating intercompany invoices between companies using different tax regions. The fix ensures accurate tax calculations by correctly applying and recomputing taxes based on the intended fiscal position, preventing incorrect error messages. This improves the reliability of intercompany transactions.
Original PR description
**Steps to reproduce:** * Install the *Accounting* module. * Install localisation modules for two different regions: * *Belgium* (**l10n_be**) * *Luxembourg* (**l10n_lu**) * Configure two companies,…
**Steps to reproduce:** * Install the *Accounting* module. * Install localisation modules for two different regions: * *Belgium* (**l10n_be**) * *Luxembourg* (**l10n_lu**) * Configure two companies, each assigned to one of the above regions. * Create fiscal positions: * In the Belgium company, create a fiscal position for Luxembourg. * In the Luxembourg company, create a fiscal position for Belgium. * Go to *Accounting > Configuration > Settings*. Enable *Inter-Company Transactions*. Enable synchronization of *Vendor Bills and Invoices* for both companies. * Create an invoice in the Luxembourg company. Select a partner belonging to the Belgium company. Add a product with applicable taxes. **Observed behavior:** * A validation error is raised: 'This entry contains taxes that are not compatible with your fiscal position. Please check the country set in the fiscal position and in your tax configuration.' **Cause:** * During intercompany bill creation, a foreign fiscal position is applied before recomputing taxes. * If no mapped foreign taxes exist, the system keeps domestic purchase taxes. * This leads to a mismatch between taxes and fiscal position, triggering the validation error. **Fix:** * Add a safeguard in *_inter_company_create_invoices()*. * After *_inter_company_sync_invoice_line_taxes()* recomputes taxes, *_inter_company_has_incompatible_fiscal_position_taxes()* checks whether the fiscal position is incompatible. * If incompatible, the fiscal position is removed and taxes are recomputed without it. opw-6103671
This update resolves a duplication issue where the contract type ID was appearing twice in the HR offer form view for the Belgian localization. The code was corrected to ensure consistent contract type definitions across modules, preventing errors and improving data accuracy. This change is specific to version 17 and will be addressed in a separate PR after that.
Original PR description
[IMP] hr_contract_salary: fix contract_type_id definition The definitions of the contract_type_id in hr_contract_salary_offer and l10n_be_hr_contract_salary/hr_contract_salary_offer should be same I converted the definition of contract_type_id in the base module to the Belgium one. Also, the contract_type_id was inserted to the view in Belgium one as well, I deleted that part to prevent double appearance. This task is only for v.17, after this version I will open a new PR to handle them. Do not forward the task after v.17 (only for v.17) task - 6101717
This update fixes an issue where discount lines in Czech VAT reports (vies) were incorrectly calculated. The previous system applied an absolute value function, leading to inflated report totals. The fix now correctly handles negative discount amounts, ensuring accurate VAT reporting for Czech companies.
Original PR description
Step to reproduce: - install l10n_cz_reports_2025 and switch to cz company - create a invoice, with cz company ( as partner), of 100. - when adding products, add "Transaction code" (optional fields) to "Goods" - Add discount line, set to -10, add "Transaction code" in this line too. - confirm it Observation: - invoice is 90$ - open vies summary report for this year - value turn out to 110 Cause: - commit [1](https://github.com/odoo/enterprise/commit/892268c44b1bbc838a9f03ef36a079bfff625ca6) converts every balance to +ve and only negate it, in case of refund - in case of discount lines, price is -ve, ABS() turn it to +ve and value comes out to be wrong Fix: - instead of applying ABS() directly, we flip the signs only for out_* moves, in short when a account is credited, its balance is < 0 then we flip its sign opw- 5979262