Daily updates from Odoo
Saturday, July 11, 2026
40 changes
5 changes
New functionality added to Odoo
Users can now instantly fetch e-invoices from the Polish KSeF platform directly within Odoo, eliminating the need for scheduled updates. This new 'Fetch e-Invoices' action, accessible through the gear icon, provides immediate control over document synchronization, ensuring data accuracy and compliance.
Original PR description
Previously, bills could only be retrieved from the KSeF platform via a scheduled cron job, leaving users with no option to manually sync documents on demand. An "Import from KSeF" action has been added to the gear (cog) menu within both the list and Kanban views. Clicking this option triggers the synchronization process immediately and reloads the active view. Task [link](https://www.odoo.com/odoo/project.task/6306892) task-6306892 Forward-Port-Of: odoo/odoo#274798 Forward-Port-Of: odoo/odoo#271459
Enhancements to existing features
The Time Off planning Gantt view now uses paging and opens with an overview-style scale by default. This should make larger schedules easier and faster to browse, improving usability for managers reviewing leave plans.
Original PR description
Add paging and default scale as the overview gantt task-6381315 Forward-Port-Of: odoo/enterprise#123936
Resolved issues and error corrections
The project Gantt view now consistently shades unavailable periods when users work across multiple companies. This prevents confusion by making approved time off visible in the schedule even when several companies are selected.
Original PR description
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and…
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and create a task during the approved time-off period the warning is shown and the Gantt cell is grayed out. - Select both companies and create a task during the same time-off period in Tasks > Gantt. Issue: When multiple companies are selected, the time-off warning is still displayed but the corresponding Gantt cells are no longer grayed out, leading to an inconsistency between the warning logic and the Gantt rendering. Cause: In multi-company setups, a user can be linked to multiple resources. The Gantt unavailability logic assumed a one-to-one relationship between user and resource causing unavailability intervals from some resources to be overwritten. Solution: Aggregate unavailability intervals from all resources linked to the same user, limited to the selected companies, and merge them with the company calendar unavailability to ensure consistent Gantt gray rendering. Related PR: https://github.com/odoo/enterprise/pull/57028 task-5089385 Forward-Port-Of: odoo/enterprise#123732 Forward-Port-Of: odoo/enterprise#105288
This update fixes an issue where combo lines weren't being imported correctly, leading to inaccurate calculations. The fix allows users to now specify combo item IDs during import, ensuring combo line amounts are calculated accurately and imported successfully.
Original PR description
Issue: --- Importing combo lines from file is not working correctly. Combo amounts are not correctly calculated. Cause: --- Currently we cannot set `combo_item_id` field in import file, as filling it will cause import fail on `ensure_one()` being called on `lined_lines` while no line is still created. Fix: --- The proposition here is to pop the `combo_item_id` in import while creating SOLs and then writing these fields values after records are created. This will allow users to set `combo_item_id` in order to be able to import combo lines. opw-6355560 Forward-Port-Of: odoo/odoo#275069
This update ensures that the customer's phone number is consistently saved when placing orders through a self-order kiosk (like a payment terminal). Previously, the phone number was lost during a payment processing step. This change corrects a bug that prevented accurate order information from being recorded, improving the customer experience.
Original PR description
When ordering from a self-order kiosk (e.g. with a Stripe payment terminal), the customer's phone number was saved on the created partner but no longer on the order itself (pos.order.mobile stayed…
When ordering from a self-order kiosk (e.g. with a Stripe payment terminal), the customer's phone number was saved on the created partner but no longer on the order itself (pos.order.mobile stayed empty), while the email was correctly registered. Self-order (QR code / mobile) was not affected. Steps to reproduce: ------------------- * Set a POS in kiosk mode with a payment terminal * Place an order and fill in the contact information (email & phone) * Pay through the terminal * Open the order in the backend > Observe that the email is registered but the phone (mobile) is not Why the fix: ------------ The kiosk pays through a second server round-trip (/kiosk/payment), which runs _check_pos_order again on the already created order. There, 'email' falls back to the partner's email but 'mobile' was taken only from the payload. By payment time the phone is no longer in the frontend payload (it is stripped from every self-order response), so the second sync overwrote the mobile saved on the draft with an empty value. The email survived only thanks to its partner fallback. Mirror the email behaviour and fall back to the partner's phone so the mobile survives the payment re-sync, consistently with the mobile field being computed from the partner. opw-6331335 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273679
4 changes
New functionality added to Odoo
This update allows users to immediately fetch invoices from the Polish KSeF platform directly from within Odoo. Previously, invoices were only retrieved through a scheduled process. This new 'Fetch e-Invoices' action provides greater control and flexibility for users needing to sync their documents promptly.
Original PR description
Previously, bills could only be retrieved from the KSeF platform via a scheduled cron job, leaving users with no option to manually sync documents on demand. An "Import from KSeF" action has been added to the gear (cog) menu within both the list and Kanban views. Clicking this option triggers the synchronization process immediately and reloads the active view. Task [link](https://www.odoo.com/odoo/project.task/6306892) task-6306892 Forward-Port-Of: odoo/odoo#274798 Forward-Port-Of: odoo/odoo#271459
Enhancements to existing features
The Time Off planning Gantt view now uses paging and opens at an overview scale by default. This should make larger schedules easier to browse and improve performance when viewing many records.
Original PR description
Add paging and default scale as the overview gantt task-6381315 Forward-Port-Of: odoo/enterprise#123936
Resolved issues and error corrections
The Tasks Gantt view now correctly shows unavailable time slots when a user has employees in multiple selected companies. This keeps time-off warnings and greyed-out scheduling cells consistent, helping planners avoid assigning work during approved absences.
Original PR description
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and…
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and create a task during the approved time-off period the warning is shown and the Gantt cell is grayed out. - Select both companies and create a task during the same time-off period in Tasks > Gantt. Issue: When multiple companies are selected, the time-off warning is still displayed but the corresponding Gantt cells are no longer grayed out, leading to an inconsistency between the warning logic and the Gantt rendering. Cause: In multi-company setups, a user can be linked to multiple resources. The Gantt unavailability logic assumed a one-to-one relationship between user and resource causing unavailability intervals from some resources to be overwritten. Solution: Aggregate unavailability intervals from all resources linked to the same user, limited to the selected companies, and merge them with the company calendar unavailability to ensure consistent Gantt gray rendering. Related PR: https://github.com/odoo/enterprise/pull/57028 task-5089385 Forward-Port-Of: odoo/enterprise#123732 Forward-Port-Of: odoo/enterprise#105288
This update resolves an issue where combo lines weren't being imported correctly, leading to inaccurate calculations. The fix allows users to specify combo items during import, ensuring accurate totals and proper handling of combo products within sales orders.
Original PR description
Issue: --- Importing combo lines from file is not working correctly. Combo amounts are not correctly calculated. Cause: --- Currently we cannot set `combo_item_id` field in import file, as filling it will cause import fail on `ensure_one()` being called on `lined_lines` while no line is still created. Fix: --- The proposition here is to pop the `combo_item_id` in import while creating SOLs and then writing these fields values after records are created. This will allow users to set `combo_item_id` in order to be able to import combo lines. opw-6355560 Forward-Port-Of: odoo/odoo#275069
6 changes
New functionality added to Odoo
This update allows users to instantly fetch e-invoices from the Polish KSeF system directly from the Odoo interface. Previously, invoices needed to be synced via a scheduled process. This new 'Fetch e-Invoices' action provides immediate control and ensures users always have the latest data.
Original PR description
Previously, bills could only be retrieved from the KSeF platform via a scheduled cron job, leaving users with no option to manually sync documents on demand. An "Import from KSeF" action has been added to the gear (cog) menu within both the list and Kanban views. Clicking this option triggers the synchronization process immediately and reloads the active view. Task [link](https://www.odoo.com/odoo/project.task/6306892) task-6306892 Forward-Port-Of: odoo/odoo#274798 Forward-Port-Of: odoo/odoo#271459
Enhancements to existing features
This update introduces a manual process for Know Your Customer (KYC) verification within the PEPPOL account setup in Odoo. Previously, this process was automated. Now, administrators can complete the necessary KYC documentation directly within Odoo, ensuring compliance and streamlining the account onboarding experience. This change improves the user experience and simplifies the regulatory requirements for PEPPOL accounts.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275371
Resolved issues and error corrections
This update resolves an issue where sales orders could incorrectly show analytic distributions exceeding 100%, leading to confusing financial reporting. The change consolidates analytic distributions from multiple models into a single line, maintaining functionality while ensuring accurate reporting. This improves clarity and prevents potential over-allocation of costs.
Original PR description
Steps: 1. Create an analytic model filtered by partner. 2. Create an analytic model filtered by product. 3. Create a project with an analytic distribution. (Make sure the distributions use different plans) 4. Create an SO for a product within the project that both the models apply to. 5. Confirm the SO. 6. Notice the analytic distribution for the project account is at 200%. When an SOL is created, the analytic distribution from each model is added as a separte line The analytic account for the project is added to each analytic distribution line. This can easily cause the account to have >100% distribution for a given SOL. This is unintuitive and confusing behaviour. This PR changes the behaviour to only create one line for all the distributions from analytic models. This should prevent this behaviour while keeping the functionality of applying the project distribution to each line. opw-6250908 / opw-6304033 Forward-Port-Of: odoo/odoo#270151
This update fixes an issue where combo lines weren't being imported accurately due to a technical limitation in the import process. The fix allows users to correctly specify combo items during import, ensuring accurate calculation of quantities and prices for combo orders. This improves the reliability of sales order imports.
Original PR description
Issue: --- Importing combo lines from file is not working correctly. Combo amounts are not correctly calculated. Cause: --- Currently we cannot set `combo_item_id` field in import file, as filling it will cause import fail on `ensure_one()` being called on `lined_lines` while no line is still created. Fix: --- The proposition here is to pop the `combo_item_id` in import while creating SOLs and then writing these fields values after records are created. This will allow users to set `combo_item_id` in order to be able to import combo lines. opw-6355560 Forward-Port-Of: odoo/odoo#275069
This update ensures that the customer's phone number is consistently saved when placing orders via a self-order kiosk (like a payment terminal). Previously, the phone number was lost during a payment processing step. This change corrects a bug that prevented the phone number from being recorded, improving order accuracy and customer communication.
Original PR description
When ordering from a self-order kiosk (e.g. with a Stripe payment terminal), the customer's phone number was saved on the created partner but no longer on the order itself (pos.order.mobile stayed…
When ordering from a self-order kiosk (e.g. with a Stripe payment terminal), the customer's phone number was saved on the created partner but no longer on the order itself (pos.order.mobile stayed empty), while the email was correctly registered. Self-order (QR code / mobile) was not affected. Steps to reproduce: ------------------- * Set a POS in kiosk mode with a payment terminal * Place an order and fill in the contact information (email & phone) * Pay through the terminal * Open the order in the backend > Observe that the email is registered but the phone (mobile) is not Why the fix: ------------ The kiosk pays through a second server round-trip (/kiosk/payment), which runs _check_pos_order again on the already created order. There, 'email' falls back to the partner's email but 'mobile' was taken only from the payload. By payment time the phone is no longer in the frontend payload (it is stripped from every self-order response), so the second sync overwrote the mobile saved on the draft with an empty value. The email survived only thanks to its partner fallback. Mirror the email behaviour and fall back to the partner's phone so the mobile survives the payment re-sync, consistently with the mobile field being computed from the partner. opw-6331335 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273679
This update resolves an issue where cloud attachments downloaded through signed URLs were saved with generic names. The fix ensures that the correct file names and types are used when downloading attachments from cloud storage services like Azure and Google, improving the user experience and data integrity.
Original PR description
Cloud attachments downloaded through signed URLs were saved with generic blob names because the link did not carry the original mimetype. Embed Content-Disposition and Content-Type in Azure and Google download URLs, and set Content-Type when uploading. GCS signed URL v4 validation requires alphabetically sorted query parameters once response headers are added to the signature. task-6359564 https://github.com/odoo/documentation/pull/18771 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275700 Forward-Port-Of: odoo/odoo#274019
4 changes
Enhancements to existing features
This update allows users to instantly fetch e-invoices from the Polish KSeF system directly from their Odoo interface. Previously, invoices were only synced automatically on a schedule. This new 'Fetch e-Invoices' action provides immediate control and ensures users always have the latest data.
Original PR description
Previously, bills could only be retrieved from the KSeF platform via a scheduled cron job, leaving users with no option to manually sync documents on demand. An "Import from KSeF" action has been added to the gear (cog) menu within both the list and Kanban views. Clicking this option triggers the synchronization process immediately and reloads the active view. Task [link](https://www.odoo.com/odoo/project.task/6306892) task-6306892 Forward-Port-Of: odoo/odoo#274798 Forward-Port-Of: odoo/odoo#271459
Resolved issues and error corrections
This update resolves an issue where cloud attachments downloaded via signed URLs were saved with generic names, preventing correct display and functionality. The changes ensure that attachment names accurately reflect the original file type and are correctly handled during download, improving the user experience.
Original PR description
Cloud attachments downloaded through signed URLs were saved with generic blob names because the link did not carry the original mimetype. Embed Content-Disposition and Content-Type in Azure and Google download URLs, and set Content-Type when uploading. GCS signed URL v4 validation requires alphabetically sorted query parameters once response headers are added to the signature. task-6359564 https://github.com/odoo/documentation/pull/18771 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274019
This update fixes an issue where combo lines weren't being imported correctly, leading to inaccurate calculations. The fix allows users to specify combo items during import, ensuring accurate totals and proper handling of combo orders.
Original PR description
Issue: --- Importing combo lines from file is not working correctly. Combo amounts are not correctly calculated. Cause: --- Currently we cannot set `combo_item_id` field in import file, as filling it will cause import fail on `ensure_one()` being called on `lined_lines` while no line is still created. Fix: --- The proposition here is to pop the `combo_item_id` in import while creating SOLs and then writing these fields values after records are created. This will allow users to set `combo_item_id` in order to be able to import combo lines. opw-6355560 Forward-Port-Of: odoo/odoo#275069
This update ensures that customer phone numbers are consistently saved for orders placed through self-order kiosks (like payment terminals). Previously, the phone number was lost during a payment processing step. This change mirrors the behavior of email registration, ensuring accurate order information is always captured.
Original PR description
When ordering from a self-order kiosk (e.g. with a Stripe payment terminal), the customer's phone number was saved on the created partner but no longer on the order itself (pos.order.mobile stayed…
When ordering from a self-order kiosk (e.g. with a Stripe payment terminal), the customer's phone number was saved on the created partner but no longer on the order itself (pos.order.mobile stayed empty), while the email was correctly registered. Self-order (QR code / mobile) was not affected. Steps to reproduce: ------------------- * Set a POS in kiosk mode with a payment terminal * Place an order and fill in the contact information (email & phone) * Pay through the terminal * Open the order in the backend > Observe that the email is registered but the phone (mobile) is not Why the fix: ------------ The kiosk pays through a second server round-trip (/kiosk/payment), which runs _check_pos_order again on the already created order. There, 'email' falls back to the partner's email but 'mobile' was taken only from the payload. By payment time the phone is no longer in the frontend payload (it is stripped from every self-order response), so the second sync overwrote the mobile saved on the draft with an empty value. The email survived only thanks to its partner fallback. Mirror the email behaviour and fall back to the partner's phone so the mobile survives the payment re-sync, consistently with the mobile field being computed from the partner. opw-6331335 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273679
21 changes
New functionality added to Odoo
Odoo can now recognize and contact WhatsApp users through business-scoped user IDs when phone numbers are not shared. This helps businesses continue conversations reliably and match contacts more accurately across WhatsApp and Odoo.
Original PR description
Add support for whatsapp business-scoped user ids as outline in the [documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/business-scoped-user-ids) for their introduction this June. This effectively adds a table mapping BSUID to contacts to enable contacting users who contact the business directly, as the business will now not necessarily be provided with their number. Additionally the “whatsapp id”, i.e. the canonical form of the phone number as stored in whatsapp, is stored to help better match contacts regardless of formatting details in odoo and whatsapp. task-5476552 Forward-Port-Of: odoo/enterprise#117782
Enhancements to existing features
VoIP call lists now offer an easier-to-understand grouping option that shows friendly labels such as Contact or Task instead of technical model names. The related document ID field was also clarified in custom searches, while keeping the main view label simple for everyday users.
Original PR description
Steps that were improved: - VoIP calls list view - Search -> Group by -> Custom Group -> "Related Document Model" - Grouping appears with values like "res.partner", "project.task", etc => That is fine but it would be better to have "Contact", "Task", etc => There is now a "Logged On" custom group that is there for that and easier to find. Also renamed "Logged On" m2o reference field to "Logged On (ID)" to have a distinction with the new "Logged On" in custom searches (those custom searches can only be used if you know the exact numeric ID anyway). The view still display "Logged On" as the label of that m2o reference though to appear less technical. task-6234384
Belgian payroll rules now include the updated employment bonus parameters effective 1 July 2026 and 1 September 2026. This helps ensure payslip calculations remain aligned with upcoming Belgian legal payroll requirements.
Original PR description
Update the employment bonus parameters for 1st July 2026 and 1st September 2026. task-6369633 Forward-Port-Of: odoo/enterprise#123566 Forward-Port-Of: odoo/enterprise#123262
Deleting attachments linked to Chilean electronic invoicing and stock documents is now much faster, especially in databases with large volumes of accounting moves and deliveries. This reduces waiting time and improves system responsiveness during cleanup or document management operations.
Original PR description
## The problem Deleting attachments checks foreign key triggers. Lookups in `account_move` and `stock_picking` tables for `ir_attachment` related fields coming from `l10n_cl_edi` overrides were slow due to missing indexes. ## The solution Added needed indexes to optimize triggers' lookups. ## Benchmark Time benchmark (deleting attachments from a customer database with 224K account moves and 204K stock pickings): |# of rows|Time (Before)|Time (After)| |----------|--------------|-------------| 100 | 29s | 16ms 1000 | 285s | 300ms OPW-6331845 Forward-Port-Of: odoo/enterprise#123350 Forward-Port-Of: odoo/enterprise#123252
The time off planning Gantt view now uses paging and opens at a broader overview scale by default. This should make large leave schedules easier to load, browse, and review for managers and HR teams.
Original PR description
Add paging and default scale as the overview gantt task-6381315 Forward-Port-Of: odoo/enterprise#123936
Resolved issues and error corrections
This fix ensures barcode users cannot add or scan unreserved products when an operation type has extra products disabled. It keeps inventory workflows aligned with configured controls and prevents accidental stock discrepancies after reserved items are completed.
Original PR description
# How to reproduce - Go to Inventory > Settings > Operation Types - Pick any Operation and disable "Allow extra product" - Create a picking for that operation type with atleast one product and click…
# How to reproduce - Go to Inventory > Settings > Operation Types - Pick any Operation and disable "Allow extra product" - Create a picking for that operation type with atleast one product and click on "Mark as Todo" - Go to the Barcode app and find the created picking - Scan all the reserved products - Exit the picking and re-enter # The problem The "Add Product" button is displayed and you can scan unreserved products even tough you sould not be allowed to # Cause of the issue The problem stems from the fact that even with "Allow extra product" disabled, we still allow to add unreserved products for immediate transfers (created directly in the barcode app). The issue is that we don't really have a way to distinguish immediate transfers from plannified ones made in the Inventory app. So we try to guess using the `_useReservation` attribute (If it is false, we allow additional products). `_useReservation` is computed as follows : if any move lines from the inital state is not yet picked, set it to true : https://github.com/odoo/enterprise/blob/ca4b369e4fc9f4655574cf1ca71c81faaadc3e88/stock_barcode/static/src/models/barcode_picking_model.js#L43 So in our case, once all the reserved products are scanned, all the initial move lines are picked and our guessing fails. # Proposed Solution Since immediate transfers are never validated and stays in draft mode, guess using the state of the current picking in addition to `useReservation` opw-6231238 Forward-Port-Of: odoo/enterprise#118378
Default website dynamic snippets now use the correct filter references regardless of the order modules were installed. This prevents generated websites and sales pages from showing incorrect or broken dynamic content when installations differ.
Original PR description
Our default dynamic snippets filter ids are set based on the order that we install our modules. This can cause issues if the user installs their modules in a different order. To fix this, we need to update the data-filter-id value to the correct value of the DB. To be able to do this, we also change the regex replacement to use lxml instead since it's much simpler. Lxml part from 799f83575e162eb683cfaebb4eb602ccc1fbe466. Forward-Port-Of: odoo/enterprise#123634 Forward-Port-Of: odoo/enterprise#122671
This fix ensures point-of-sale planning correctly considers all resources when a payment method is not tied to a specific resource. It also limits planning slot selection to the same company as the POS configuration, helping avoid incorrect cross-company availability.
Original PR description
When no resource is linked to a resource payment method, we should take into account all resource which was not done before. This is now done. We also change the filter in python to only look for slots that are part of the same company as the config. Forward-Port-Of: odoo/enterprise#121909
Payroll work entries generated from attendances no longer create duplicate entries when a worked-time leave overlaps a public holiday. This helps ensure employees' payroll days are counted correctly, especially for flexible schedules and sandwich-rule leave scenarios.
Original PR description
Issue: When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day.…
Issue: When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day. Steps to reproduce: - Create an employee with Work Entry Source set to Attendances - Use a flexible working schedule on the employee - Configure a public holiday on a scheduled day with work entry type (Paid time off) - Create a time off type with Count as set to Worked Time - Generate time off for the period so the public holiday entry exists (maybe a day before and a the public holiday and the day after) - Open Payroll > Work Entries (Observe the date of the public holiday will have more than 8h entry) Cause: In `_get_version_work_entries_values()`, calendar leaves are split by `hr_holidays` `time_type` into: - leaves: absences and public holidays - worked_leaves: worked-time time off For attendance-based contracts, both sets were turned into work entries without removing overlap between a public holiday and a worked-time leave on the same period. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L222-L226 For non-flexible calendar: Public holidays and worked-time leaves are both clipped to the static working schedule (e.g. 8h per working day). overlap was kept in both result sets. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L260 For flexible calendar: The one-day intervals are kept as the actual interval (often 00:00-23:59 for a public holiday). The worked-time on that day is schedule-shaped (e.g. 8h). Subtracting intervals on a full-day public holiday left a 16h fragment instead of removing the public holiday entry. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L242-L249 Solution: We need to make regular leaves take priority over worked-time leaves, compute the real regular leave intervals first, then remove those intervals from the worked-time leave intervals before work entries are created: - for fully flexible employees, subtract regular leaves from worked leaves; - for flexible calendars, keep one-day regular leaves as is and subtract them from worked-time leaves - for non-flexible attendance-based calendars, clip regular leaves on the static schedule, then subtract them from worked-time leaves clipped on the same schedule. This means that when a sandwich worked-time leave overlaps a public holiday, the public holiday consumes that period first. The overlapping part is then removed from `real_worked_leaves`, so no second worked-time entry is generated for the same public holiday period. opw-6237163 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#122126 Forward-Port-Of: odoo/enterprise#119530
Fixed an issue where expanding a folded Knowledge article could show only favorited child articles while hiding the other children. Users can now reliably see the complete article hierarchy in the sidebar without needing to reload.
Original PR description
The sidebar always loads the user's favorite articles along with the visible ones, so a favorited article is shown as a root of the favorite tree. When that favorite is also a child of a folded…
The sidebar always loads the user's favorite articles along with the visible ones, so a favorited article is shown as a root of the favorite tree. When that favorite is also a child of a folded article, it gets added to its parent's child_ids in the main tree, even though the parent's other children were not fetched. A folded article only gets its favorited children back from get_sidebar_articles, not its whole child set. When the parent is then unfolded, unfold() only read the children from the database when child_ids was empty. The favorited child already filled child_ids, so the call was skipped and the remaining children stayed hidden until the next reload. unfold() now uses a new children_loaded flag instead of the length of child_ids to decide whether to fetch the children. The flag is set once an article's whole child set is loaded: in loadChildren(), and in loadArticles() for the articles that were unfolded, since those come back with all their children. loadChildren() also rebuilds child_ids from the search result so a favorite already loaded is not added twice. The fix lives in the sidebar component because the partial child_ids only exists on the frontend, get_sidebar_articles already returns the right records. Steps to reproduce: 1. Open the Knowledge app 2. Create an article with two child articles 3. Add one of the two children to your favorites with the star icon 4. Open another article that is not under that parent 5. Fold the parent article in the sidebar, then refresh the page 6. Expand the parent article => only the favorited child is shown under the parent, the other child is missing Ticket [link](https://www.odoo.com/odoo/project.task/6186466) opw-6186466 Forward-Port-Of: odoo/enterprise#118804
GSTR-1 spreadsheets now report SEZ invoices issued in foreign currencies using the company currency, INR, instead of the original foreign currency. This helps businesses submit accurate Indian GST return data and avoids mismatches in reported invoice values.
Original PR description
Currently, when generatign GSTR-1 return spreadshee, SEZ invoices issued in a foreign currency are exported with their totals in the foreign currency rather than the company currency (INR) Steps to reproduce: - Create a B2B SEZ invoice in foreign currency - Go to Accounting > Reporting > [India] GST Return periods - Generate the GSTR-1 report for the period Issue: In the resulting spreadsheet, the "Invoice Value" column takes the invoice total in USD rather then INR opw-6292913 Forward-Port-Of: odoo/enterprise#122514 Forward-Port-Of: odoo/enterprise#121157
Foreign EU VAT invoices over 10,000 CZK are now placed in the correct section of the Czech VAT control statement. This prevents non-domestic transactions from being incorrectly reported as domestic, improving compliance accuracy.
Original PR description
With l10n_cz company: - Create an invoice for a partner with a foreign vat (EU) with an amount greater than 10000 CZ and a 21% tax. In the vat control statement of the tax report, the move is classified under A4. But the section A4 should only contain move with domestic vat opw-6268506 Forward-Port-Of: odoo/enterprise#120002
AI-related screens now display better on smaller devices, with cleaner layouts for agent profiles, composer cards, and skill forms. This makes the AI tools easier to read and use on phones and tablets by reducing wasted space and positioning key information more clearly.
Original PR description
This commit improves the user experience of the AI modules on smaller screens by fixing several views for mobile devices. The changes include: - Adapt the AI agent form view to follow the Contacts mobile layout by centering the avatar in a circular container and improving the layout of the name and description. - Move the agent avatar next to the record name in the AI Composer kanban view to optimize space usage. - Remove unnecessary empty space in the AI Skill form view so the form uses the available width on mobile. task-6366399 Forward-Port-Of: odoo/enterprise#123688
The website now shows the exact discount percentage configured for subscription products when prices are displayed with taxes included. This prevents customers from seeing a lower discount than intended, such as 4% instead of 5%, improving pricing clarity and trust during checkout.
Original PR description
Steps to reproduce: 1. Install eCommerce and Subscriptions. 2. Create a 21% Excluded tax. 3. Create a subscription product with a price of 45 with 21% tax and enable "Accept One-Time" in the…
Steps to reproduce: 1. Install eCommerce and Subscriptions. 2. Create a 21% Excluded tax. 3. Create a subscription product with a price of 45 with 21% tax and enable "Accept One-Time" in the Recurring Prices tab. 4. Publish the product on the website under the Sales tab. 5. Create a pricelist for 6 months recurring with two lines: - If min quantity is 0, then 0% discount - If min quantity is 2, then 5% discount 6. Set "Display Product Prices" to "Tax Included" in the Settings. 7. Open the product on the website, select the 6-month plan, and increase quantity to 2. Issue: The discount percentage displayed on the website shows 4% instead of the configured 5%. Why this happens: In `_get_additionnal_combination_info`, the discount is reverse-calculated from the tax-included price vs the tax-included sales price. When the 21% tax is included to both prices, it introduces a floating-point precision loss (4.9954..%), which floor() then truncates to 4%. Fix: When the pricelist rule uses 'percentage' discount, read `percent_price` directly from the pricing rule instead of reverse-calculating from tax-adjusted prices, as it represents the exact discount percentage the merchant configured with no floating-point involvement. opw-6224735 Forward-Port-Of: odoo/enterprise#121654
Point of Sale online orders from UrbanPiper and related platforms are now fetched together instead of through multiple separate requests. This reduces waiting time during order refreshes and lowers unnecessary server traffic, improving day-to-day POS responsiveness.
Original PR description
Issue: pos_urban_piper overrode getServerOrders() to add a separate loadServerOrders() call for it's own orders before delegating to super, resulting in up to an additional sequential RPCs on every order fetch. Fix: Extract the base query domain into a new overridable getServerOrdersDomain() method. Each module overrides it to OR in its own domain via Domain.or([super.getServerOrdersDomain(), extraDomain]), so all orders are fetched in a single RPC call instead of three. Task-6284860 Forward-Port-Of: odoo/enterprise#123679 Forward-Port-Of: odoo/enterprise#120001
The Argentine VAT Book ZIP export no longer fails for partners marked as foreign providers with a foreign ID. This helps accounting users complete VAT reporting for cross-border transactions without manual workarounds.
Original PR description
Steps to reproduce: - Create a partner with: - State: Ireland - Identification Number: Foreign ID 55000004153 - ARCA Responsibility Type: Proveedor del Exterior - Create an invoice for the partner - Accounting > Reporting > Tax report - Select Report: VAT Book (AR), Tax Type: Sales - Click on gear icon > VAT Book (ZIP) Issue: Action will be blocked with error "No VAT configured for partner [58] <partner>" Analysis: Partners with ARCA responsibility type 'Proveedor del Exterior' (code 8) and a ForeignID identification type, causes a UserError when exporting the VAT Book (ZIP). Code 8 (foreign provider) is the purchase-side counterpart of code 9 (foreign customer), which already fell back to the country-level VAT. Extend the existing fallback branch to cover both codes. opw-6316008 Forward-Port-Of: odoo/enterprise#123506
Kenyan POS refund validation now works reliably without showing an error after a refunded sale. The fix also improves handling when multiple offline POS orders sync together, ensuring orders are sent to eTIMS correctly without disrupting cashier workflows.
Original PR description
Steps to reproduce: 1. Install `l10n_ke_edi_oscu_pos`, set company to Kenya. 2. Sell and validate an order. 3. Refund it from the POS and validate the refund order. Issue: - A traceback is raised…
Steps to reproduce: 1. Install `l10n_ke_edi_oscu_pos`, set company to Kenya. 2. Sell and validate an order. 3. Refund it from the POS and validate the refund order. Issue: - A traceback is raised when validating the refund: `ValueError: Expected singleton: pos.order(<refund>, <original>)` raised in `get_l10n_ke_edi_oscu_pos_data`. Cause: - When syncing a refund, `sync_from_ui` returns both the new refund order and the original refunded order. `waitForPushOrder` forces post-processing for every Kenyan order in that list, so `beforePostPushOrderResolve` receives both ids in `order_server_ids` and forwards them as-is to `action_post_order` and `get_l10n_ke_edi_oscu_pos_data`, both of which expect a single record. `action_post_order` fails the same way, but its error was silently swallowed by the surrounding try/catch, letting the traceback surface only on the second call. - The same multi-id list is also produced whenever several orders created offline get synced together once back online. Solution: - `get_l10n_ke_edi_oscu_pos_data` is only needed for the receipt of the order being validated, so call it with `order.id` instead of the full `order_server_ids` list. - Replace the `action_post_order` call with `action_post_selected_orders`, which posts each order individually and skips ones already sent to eTIMS, correctly handling both the refund case (original order is already `sent`) and the offline multi-order sync case. opw-6364221 Forward-Port-Of: odoo/enterprise#123043
This update fixes several small issues in accounting reports, including an unnecessary currency warning, a crash when dismissing warnings too quickly, and confusing audit behavior for budget-related values. It also hides an irrelevant setup field for composite reports and improves the appearance of working file cards, making reports clearer and more reliable for users.
Original PR description
**Commit 1: [FIX] account_reports: warning for CTA visibility** Steps to reproduce: - Open the balance sheet -> The warning for CTA is displayed even when a single company is selected. It should only…
**Commit 1: [FIX] account_reports: warning for CTA visibility**
Steps to reproduce:
- Open the balance sheet
-> The warning for CTA is displayed even when a single company is selected.
It should only be the case if multiple companies having different currencies
are involved in the computation of the report.
**Commit 2: [FIX] account_reports: hide groupby field on form view for composite report**
this field is useless for composite reports.
**Commit 3: [FIX] account_reports: differentiate UX for auditable external values.**
When creating a budget in the P&L, the external value cells should not be
auditable. The data was properly set but not the templates.
**Commit 4: [FIX] account_reports: avoid traceback on double-click on warning**
Steps to reproduce:
- Open an accounting report with any warning banner ("draft entries" for example)
- Quickly double-click the delete cross button
-> traceback stating that it cannot read properties of null (reading 'remove').
**Commit 5: [FIX] account_reports: working file card style adjustments**
<img width="401" height="317" alt="image" src="https://github.com/user-attachments/assets/76f636f0-09d8-44e5-8c7c-37561dc00b10" />
task-6361495
Forward-Port-Of: odoo/enterprise#123004Appointment blocks using picture or list layouts now show prices according to the website's tax display setting. This prevents customers from seeing tax-excluded prices when the site is configured to display tax-included pricing.
Original PR description
When the `appointments_template_picture` and `appointments_template_list` templates were added to `website_appointment_account_payment` in 19.0+, the corresponding overrides in `website_appointment_sale` were not added. This caused the picture and list appointment blocks to display prices using `product_lst_price` (always tax-excluded), ignoring the website's tax display setting (`show_line_subtotals_tax_selection`). The cards template already had a proper override using `_get_combination_info()`, which correctly handles everything. Steps to reproduce: 1. Go to Website > Configuration > Settings > enable "Tax Included" 2. Create an appointment type with a product that has taxes 3. Edit website page > add "Appointments" snippet > select "Picture" or "List" layout => price shown is tax-excluded Ticket [link](https://www.odoo.com/odoo/project.task/5799252) opw-5799252 Forward-Port-Of: odoo/enterprise#123448 Forward-Port-Of: odoo/enterprise#106643
Philippine 2306/2307 reports now correctly include withholding taxes that are recorded when a vendor bill is paid, rather than only when the bill is created. This prevents missing or incorrectly signed income payment amounts, helping businesses produce accurate tax reports.
Original PR description
Withholding taxes flagged as withhold-at-payment book their tax line on the payment's move instead of the vendor bill. This broke the 2306/2307 report two ways: the income payment base came out with the wrong sign, since bill and payment entries store it oppositely, and the per-move scoping only looked at the bill's own move, so bills paid this way had nothing to show. Normalize the base sign using the tax line's sign instead of the base's own, and extend the scoping to also match lines booked on a payment registered against the bill. task-6319767 Forward-Port-Of: odoo/enterprise#121573
The Tasks Gantt view now correctly shades unavailable time when a user has employees in multiple selected companies. This keeps the visual schedule aligned with time-off warnings, helping planners avoid assigning work during approved absences.
Original PR description
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and…
Steps to reproduce: - Create one user linked to two companies. - Create one employee per company for that user. - Select one company and approve a time off for the employee. - Open Tasks > Gantt and create a task during the approved time-off period the warning is shown and the Gantt cell is grayed out. - Select both companies and create a task during the same time-off period in Tasks > Gantt. Issue: When multiple companies are selected, the time-off warning is still displayed but the corresponding Gantt cells are no longer grayed out, leading to an inconsistency between the warning logic and the Gantt rendering. Cause: In multi-company setups, a user can be linked to multiple resources. The Gantt unavailability logic assumed a one-to-one relationship between user and resource causing unavailability intervals from some resources to be overwritten. Solution: Aggregate unavailability intervals from all resources linked to the same user, limited to the selected companies, and merge them with the company calendar unavailability to ensure consistent Gantt gray rendering. Related PR: https://github.com/odoo/enterprise/pull/57028 task-5089385 Forward-Port-Of: odoo/enterprise#123732 Forward-Port-Of: odoo/enterprise#105288