Daily updates from Odoo
Navigate
Branch
Tuesday, June 17, 2025
76 changes
34 changes
Enhancements to existing features
The payroll app menus have been reorganized to make common options easier to find and improve day-to-day navigation. A version menu item is also now available in debug mode, helping support and administrators access version details when needed.
Original PR description
Reorganise payroll menu items for better UX. Add a menu item for version in debug mode. Task: 4866864
Creating a maintenance request from a manufacturing order is now accessed through the cog menu instead of a dedicated button. This keeps the form cleaner while preserving the same action for users who need it.
Original PR description
Move the button for creating a maintenance request in the MO form view to the cog menu. Task ID: [4412425](https://www.odoo.com/odoo/my-tasks/4412425)
The Time Off overview dialog no longer shows an expand button because expanding it displayed the same information. This simplifies the interface and avoids a redundant action for users reviewing time off details.
Original PR description
This commit removes the expand button on the form dialog of the time off overview. The expand button is not necessary as axpanding the dialog shows exactly the same information. task-4784553
The barcode demo sheets were adjusted so 'Put in Pack' barcodes stay grouped under the correct section header. This makes the printed reference sheets clearer and more consistent for warehouse users scanning demo barcodes.
Original PR description
The 'Put in Pack' barcodes in the Code 128 section of the barcode demo sheet were moved from the bottom of the first page to the top of the second page. The Code 128 and Data Matrix pages have the same dimensions now. Task ID: [3981936](https://www.odoo.com/odoo/project/966/tasks/3981936)
The employee payslip shortcut now shows both employee-specific payslips and global payslips linked through payroll batches. This gives payroll teams a more complete view from the employee record and reduces the chance of missing relevant payroll documents.
This update removes older custom date and time field components in favor of the standard Odoo date/time field options. This keeps Sign and Appraisals easier to maintain while preserving the same user-facing behavior for showing dates, times, or seconds.
Original PR description
sign: Remove the unused datetime_no_seconds widget
---------------
The datetime widget now supports hiding seconds, as introduced in the following commit: https://github.com/odoo/odoo/commit/0f694c84c271d33e3faa1eba0bc554ee054c7e6c
https://github.com/odoo/enterprise/commit/ef6d3e123dc416251f94c3f3d65dd4a19924e8c8
In the above commit, the usage of datetime_no_seconds was replaced with the option {'show_seconds': false}.
As a result, the datetime_no_seconds widget is no longer needed. Therefore, I have removed it in this commit.
hr_appraisal: use datetime instead of timeless_datetime
--------------
The datetime widget now supports the show_time option. commit-https://github.com/odoo/odoo/commit/c775c89173784cace1178e1f9c66e4fb19f530ad
Therefore, in this commit, we use the standard datetime widget with {'show_time': False}.The custom widget has been removed as it's no longer necessary.
task-4826302The barcode app now uses clearer wording for inventory counting screens. Renaming “Inventory Count” to “Count Inventory” and “Inventory Adjustments” to “Physical Inventory” helps users better understand the workflow and keeps labels consistent.
Original PR description
- Renamed the button 'Inventory Count' to 'Count Inventory'. - Updated the title from 'Inventory Adjustments' to 'Physical Inventory' inside Count Inventory. These changes help users better understand the purpose and improve the overall consistency of the barcode interfaces. Task ID: 4526266
Opening spreadsheets no longer shows an informational notification that could cover important controls such as filters. This makes spreadsheet access smoother and reduces interruptions for users working with documents, dashboards, sales, and quality spreadsheet views.
Original PR description
Notifications when opening a spreadsheet are not very useful and can be annoying, as they hide the buttons below them (e.g. the "Filter" button). Task: 4863675
Procurement users can now choose any contact when replenishing products through the buy route, instead of being limited to existing vendor pricelist entries. This reduces setup work while preserving the existing vendor selection and pricing logic when quantities determine the best supplier terms.
Original PR description
Description of the issue/feature this PR addresses: When using the replenish wizard, and the route is buy, as a procurement specialist, I can only use vendors in the product pricelist. However, as a…
Description of the issue/feature this PR addresses: When using the replenish wizard, and the route is buy, as a procurement specialist, I can only use vendors in the product pricelist. However, as a procurement specialist, I should be able to order a replenishment from any partner (and if the PO is confirmed this partner will be added to vendor list automatically) . Current behavior before PR: To replenish a product from a partner that is not in vendor pricelist from the replenish wizard, currently I must either add him to the pricelist or make a purchase order. Desired behavior after PR is merged: 1 Allow replenishement from any partner in the replenishement wizard, by changing the supplier search box from vendor list only to vendor first, in blue, and then all partners in normal display. 2 Allow to create and edit partner from the supplier search box (no-quick create) 3 Make sure that the logic of selecting the right vendor pricelist based on quantity logic is unaltered. mockUp: https://app.excalidraw.com/s/65VNwvy7c4X/AnCh9Yc40OQ task: 4314668 link to community PR: https://github.com/odoo/odoo/pull/212891
Manufacturing shop floor users can now adjust routing directly from a workorder, including creating another workorder or moving work to a different work center. This gives teams more flexibility to react to production needs without leaving the shop floor workflow, even when a workorder is already in progress.
Original PR description
**Desired behavior after PR is merged:**
- Add modify routing button in shopfloor workorders with the ability to create another workorder or move work centers
- Allow moving to another work center while the workorder is still in progress
Task:4850003PDFs used to create signing templates are now protected so existing form fields cannot be changed in a PDF viewer. This helps preserve document integrity and reduces the risk of unintended edits during signing workflows.
Original PR description
- Introduced `flatten_pdf` method to process base64-encoded PDFs and set all form fields as read-only by updating the `/Ff` flag. - The method reads the PDF, copies all pages, retrieves the AcroForm fields, and sets the ReadOnly flag bit for each form field. - Ensures the resulting PDF is flattened so form data cannot be modified in PDF viewers, improving document integrity for signing workflows. - Returns the flattened PDF encoded back to base64 for further use.
The portal address form no longer shows the UPS Account Number field by default. This simplifies address entry for customers and avoids displaying a carrier-specific option when UPS is not relevant or enabled.
Original PR description
The 'UPS Account Number' field was always visible on the portal user's address form, regardless of context. Introduced 5 years ago with 10892c12c62fb7d82ed55f53ffe3815298b89018, it was recently moved from `website_sale_ups` to `delivery_ups`, as it was used in the core delivery logic, not only the ecommerce one. Nevertheless, it has been considered unnecessary to keep it on the portal form, as it is displayed and chosen when necessary in the e-commerce checkout flow). Furthermore, this field was shown regardless of whether the ups carrier was enabled and published (or was ever used by the current customer). We remove it for now to simplify the default address form (and runbot form). If needed, we'll consider re-introducing it in the future (but with additional restrictions). task-4669485
The online shop rental date picker no longer shows an extra month, making date selection clearer for customers. This improves the buying and renting flow by reducing visual clutter and potential confusion during checkout.
Original PR description
task-4613140
Resolved issues and error corrections
The employee form has been refreshed across HR, payroll, appraisal, documents, signing, and localized payroll modules so employee information is presented more consistently. This helps HR teams navigate employee records more easily and reduces inconsistencies between related apps.
Original PR description
Task: 4568134
Code cleanup and technical improvements
This update renames IoT driver and interface files to follow standard Python naming conventions. It is an internal cleanup that improves consistency and maintainability without changing user-facing behavior.
Original PR description
Drivers/interfaces files were still named using CamelCase instead of python standard snake_case. This commit fixes it. Community PR: odoo/odoo#208295
The website builder action system was reorganized to use a more consistent structure across appointment, rental, and studio features. This is mainly an internal improvement that makes future enhancements easier and helps keep behavior more reliable over time.
Original PR description
*: website_sale_renting, website_studio Previously, builder actions were defined as plain objects with apply/isApplied/getValue properties. This commit introduces a class-based system where each builder action extends the BuilderAction base class. Improvements include: - Support instantiated objects, and legacy object-style actions. - Greater consistency, encapsulation, and extensibility for action logic. This refactor simplifies action management and prepares the system for further enhancements like shared base logic.
Miscellaneous changes
Steps to reproduce: 1. Install the german localization 2. Create company in DE 3. Create a partner that has country = PL 4. Create a customer invoice for the PL partner 5. Open: Accounting > Reporting > EC Sales List 6. Hit the wheel and create the CSV export. 7. Open the file Issue: see that the amount is a float Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4575788) opw-4575788 Forward-Port-Of: odoo/enterprise#87421 Forward-Port-Of: odoo/enterprise#83822
Original PR description
Steps to reproduce: 1. Install the german localization 2. Create company in DE 3. Create a partner that has country = PL 4. Create a customer invoice for the PL partner 5. Open: Accounting > Reporting > EC Sales List 6. Hit the wheel and create the CSV export. 7. Open the file Issue: see that the amount is a float Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4575788) opw-4575788 Forward-Port-Of: odoo/enterprise#87421 Forward-Port-Of: odoo/enterprise#83822
Community PR: odoo/odoo#212157 Forward-Port-Of: odoo/enterprise#86650
Original PR description
Community PR: odoo/odoo#212157 Forward-Port-Of: odoo/enterprise#86650
[FIX] l10n_au_hr_payroll_account: avoid NewId warning in compute steps to reproduce: 1.install l10n_au_hr_payroll_account 2. without demo data 3. run the test test_form_new_record The compute method was being triggered too early, while the record still had a temporary NewId and not a real database ID. This caused a warning when using the field in a domain: Domains don't support NewId. We added a dependency on previous_report_id to make sure the compute only runs after the field is s
Original PR description
[FIX] l10n_au_hr_payroll_account: avoid NewId warning in compute steps to reproduce: 1.install l10n_au_hr_payroll_account 2. without demo data 3. run the test test_form_new_record The compute method was being triggered too early, while the record still had a temporary NewId and not a real database ID. This caused a warning when using the field in a domain: Domains don't support NewId. We added a dependency on previous_report_id to make sure the compute only runs after the field is set and the record is saved. This avoids the warning and keeps the logs clean. build_error-115303 Forward-Port-Of: odoo/enterprise#85292
When exploding a BoM that includes phantom (kit) components, the resulting list of components moves was not respecting the sequence order defined in the BoM. Steps to reproduce: - Create a product P1 with a BoM that includes: - Component 1 (sequence = 1) - Component 2 - KIT (sequence = 2), which itself contains: - Component 2-1 (sequence = 1) - Component 2-2 (sequence = 2) - Component 3 (sequence = 3) - Create a Manufacturing Order for P1. Observed behavior: - The
Original PR description
When exploding a BoM that includes phantom (kit) components, the resulting list of components moves was not respecting the sequence order defined in the BoM. Steps to reproduce: - Create a product P1…
When exploding a BoM that includes phantom (kit) components, the resulting list of components moves was not respecting the sequence order defined in the BoM.
Steps to reproduce:
- Create a product P1 with a BoM that includes:
- Component 1 (sequence = 1)
- Component 2 - KIT (sequence = 2), which itself contains:
- Component 2-1 (sequence = 1)
- Component 2-2 (sequence = 2)
- Component 3 (sequence = 3)
- Create a Manufacturing Order for P1.
Observed behavior:
- The generated stock moves are ordered as:
1. Component 1
2. Component 3
3. Component 2-1
4. Component 2-2
Expected behavior:
- The stock moves should respect the BoM line sequence:
1. Component 1
2. Component 2-1
3. Component 2-2
4. Component 3
Root cause:
- When exploding phantom BoMs, child lines were appended at the end of the processing queue, causing out-of-order moves:
https://github.com/odoo/odoo/blob/d64b108db54c02098c9e95f58fa3278007c92642/addons/mrp/models/mrp_bom.py#L416-L418
https://github.com/odoo/odoo/blob/d64b108db54c02098c9e95f58fa3278007c92642/addons/mrp/models/mrp_bom.py#L430
Solution:
- Insert the child BoM lines at the beginning of the processing queue (`bom_lines`), sorted by their sequence field, to ensure correct processing order.
opw-4809095
Forward-Port-Of: odoo/enterprise#87003Users can upload request documents from the kanban and the activity views. This commit extends this feature to the list view. task-4745800 Forward-Port-Of: odoo/enterprise#84518
Original PR description
Users can upload request documents from the kanban and the activity views. This commit extends this feature to the list view. task-4745800 Forward-Port-Of: odoo/enterprise#84518
- Remove useless leading zero char inside blackbox order's ticket_number. - When pushing data to blackbox we now use `keepCommands` set to true. When we serialize data in order to send it for the blackbox we won't apply the returned ORM commands, so we want to keep the data `dirty` so the next serializatin still return the commands for the ORM to execute in order to have a correct synchronization. community PR: https://github.com/odoo/odoo/pull/213361 task-id: 4848882 Forward-Port-Of: od
Original PR description
- Remove useless leading zero char inside blackbox order's ticket_number. - When pushing data to blackbox we now use `keepCommands` set to true. When we serialize data in order to send it for the blackbox we won't apply the returned ORM commands, so we want to keep the data `dirty` so the next serializatin still return the commands for the ORM to execute in order to have a correct synchronization. community PR: https://github.com/odoo/odoo/pull/213361 task-id: 4848882 Forward-Port-Of: odoo/enterprise#87193
Steps to reproduce the bug: - Create a storable product “P1” - Create a delivery order with one unit of P1, not linked to any sale order - Go to the delivery order list view - Select the created delivery order - Click on Action → Fetch shipping label Problem: A traceback is triggered: ``` ValueError: ValueError('Expected singleton: shopee.shop()') while evaluating 'records._fetch_shipment_label()' The above server error caused the following client error: ``` The `_fetch_s
Original PR description
Steps to reproduce the bug:
- Create a storable product “P1”
- Create a delivery order with one unit of P1, not linked to any sale order
- Go to the delivery order list view
- Select the created delivery order
- Click on Action → Fetch shipping label
Problem:
A traceback is triggered:
```
ValueError: ValueError('Expected singleton: shopee.shop()') while
evaluating
'records._fetch_shipment_label()'
The above server error caused the following client error:
```
The `_fetch_shipment_label` function expects at least one item, but
we don't check it via a user error, because we're supposed to call
`_sync_shopee_pickings` instead, where all these filtering and checks
are done
opw-4812360
Forward-Port-Of: odoo/enterprise#86442Added compatibility with Estonia tax report version KMD6 that is valid from 1. July 2025. For technical info please see: https://www.emta.ee/en/business-client/e-services-training-courses/how-use-e-services/technical-information-services#value-added-tax-return Forward-Port-Of: odoo/enterprise#87547 Forward-Port-Of: odoo/enterprise#84306
Original PR description
Added compatibility with Estonia tax report version KMD6 that is valid from 1. July 2025. For technical info please see: https://www.emta.ee/en/business-client/e-services-training-courses/how-use-e-services/technical-information-services#value-added-tax-return Forward-Port-Of: odoo/enterprise#87547 Forward-Port-Of: odoo/enterprise#84306
To reproduce: - As demo user, create a new sign template - Get the share url and open it in a new private window - Fill the document fields - Click on 'Validate and Send Complete Document' * enter your name and email * click on `Validate and Send` button Here nothing happen, while on server side an `AccessError` is loggued. Since https://github.com/odoo/odoo/pull/201565 we need to get new request item access_token as superuser (user who created the template might not the sufficie
Original PR description
To reproduce: - As demo user, create a new sign template - Get the share url and open it in a new private window - Fill the document fields - Click on 'Validate and Send Complete Document' * enter your name and email * click on `Validate and Send` button Here nothing happen, while on server side an `AccessError` is loggued. Since https://github.com/odoo/odoo/pull/201565 we need to get new request item access_token as superuser (user who created the template might not the sufficient rights to access it) Forward-Port-Of: odoo/enterprise#87769
Currently, employees managers with no access rights are not allowed to create a new appraisal concern for their employees. To grant managers the access to create appraisal campaigns, new customized access rule for employees' managers has been created. Also, both the Kanban and List views have been modified so that only the managers can see the "Launch Campaign" button. Forward-Port-Of: odoo/enterprise#86606
Original PR description
Currently, employees managers with no access rights are not allowed to create a new appraisal concern for their employees. To grant managers the access to create appraisal campaigns, new customized access rule for employees' managers has been created. Also, both the Kanban and List views have been modified so that only the managers can see the "Launch Campaign" button. Forward-Port-Of: odoo/enterprise#86606
As the cron generating the returns is scheduled every 3rd of the month, It might be usefull to call it manually on installation. This way the users won't have until the next call to get their returns generated. Forward-Port-Of: odoo/enterprise#87749
Original PR description
As the cron generating the returns is scheduled every 3rd of the month, It might be usefull to call it manually on installation. This way the users won't have until the next call to get their returns generated. Forward-Port-Of: odoo/enterprise#87749
A `ValueError` occurs when we set and remove values `Default Group By` in terminal when you click the cross button multiple times the view gets stuck in infinite loading screen. **Steps to reproduce:** * Install `web_studio` and `inventory` with demo data * Inventory>Toggle Studio button>View * Select any value in `Default Group By` and remove it using cross button. `ValueError: Invalid field 'None' on model 'stock.picking.type'` **Solution:** * The Javascript is passing null value
Original PR description
A `ValueError` occurs when we set and remove values `Default Group By` in terminal when you click the cross button multiple times the view gets stuck in infinite loading screen. **Steps to reproduce:** * Install `web_studio` and `inventory` with demo data * Inventory>Toggle Studio button>View * Select any value in `Default Group By` and remove it using cross button. `ValueError: Invalid field 'None' on model 'stock.picking.type'` **Solution:** * The Javascript is passing null value instead we pass an empty string. **Sentry-6618531530** Forward-Port-Of: odoo/enterprise#86206
…t mail should do Before this commit, in the reportEditor, add a field (by typing "/") There was calls made to the server that are not necessary for the report editor. This commit removes the calls by overriding the corresponding method. opw-4815802 Forward-Port-Of: odoo/enterprise#87718 Forward-Port-Of: odoo/enterprise#87425
Original PR description
…t mail should do Before this commit, in the reportEditor, add a field (by typing "/") There was calls made to the server that are not necessary for the report editor. This commit removes the calls by overriding the corresponding method. opw-4815802 Forward-Port-Of: odoo/enterprise#87718 Forward-Port-Of: odoo/enterprise#87425
When generating the accounting entry from the Corporate Tax Report, the system first tries to find a miscellaneous journal with the short code `MISC`. If this specific journal does not exist, the logic attempts to fall back and find any other journal of type 'Miscellaneous' (`type = 'general'`). However, this fallback search fails with an error due to an incorrect search domain syntax. Steps to reproduce: 1. Go to Accounting > Configuration > Journals. 2. Ensure no journal exists with th
Original PR description
When generating the accounting entry from the Corporate Tax Report, the system first tries to find a miscellaneous journal with the short code `MISC`. If this specific journal does not exist, the logic attempts to fall back and find any other journal of type 'Miscellaneous' (`type = 'general'`). However, this fallback search fails with an error due to an incorrect search domain syntax. Steps to reproduce: 1. Go to Accounting > Configuration > Journals. 2. Ensure no journal exists with the short code MISC. 3. Ensure at least one other journal of type "Miscellaneous" exists (for example, with short code GEN or MSC). 4. Go to Accounting > Reporting > Corporate Tax Report. 5. Try to generate the accounting entry. opw-4836686 Forward-Port-Of: odoo/enterprise#87300
Currently, a raceback occurs when the user changes or adds the expression label of the column in the "Generic Tax report". **To reproduce this issue:** 1) Install "account_reports" 2) Open "Generic Tax report" from "Accounting Reports" 3) In columns change the "Expression Label" and save the record 4) Open the "Tax Report" in "Reporting" 5) A traceback occurs **Error:** ``` UnboundLocalError: local variable 'col_value' referenced before assignment ``` **Cause:** The "co
Original PR description
Currently, a raceback occurs when the user changes or adds the expression label of the column in the "Generic Tax report". **To reproduce this issue:** 1) Install "account_reports" 2) Open "Generic Tax report" from "Accounting Reports" 3) In columns change the "Expression Label" and save the record 4) Open the "Tax Report" in "Reporting" 5) A traceback occurs **Error:** ``` UnboundLocalError: local variable 'col_value' referenced before assignment ``` **Cause:** The "col_value" is assigned based on the "expr_label" if it doesn't match the if conditions it leads to a traceback. https://github.com/odoo/enterprise/blob/d154cbf1bd5b4cc104ff0e2443047aff0c05330f/account_reports/models/account_generic_tax_report.py#L921-L932 **Solution:** This commit will resolve this issue by assigning a fallback value of an empty string to col_value. opw-4841789 Forward-Port-Of: odoo/enterprise#87277
Currently, the issue occurs when opening the achievement **Details** view from the commission report due to missing IDs in the view. **Steps to reproduce:** - Install the `sale_commission` module. - Create and approve a new **Commission Plan**. - Click the **Commissions** button on the form view. - From the list view, click the **Details** button for a commission entry. - Observe the error. **Error:** `ValueError: Expected singleton: sale.commission.report()` Here, an error is tri
Original PR description
Currently, the issue occurs when opening the achievement **Details** view from the commission report due to missing IDs in the view. **Steps to reproduce:** - Install the `sale_commission` module. -…
Currently, the issue occurs when opening the achievement **Details** view from the commission report due to missing IDs in the view. **Steps to reproduce:** - Install the `sale_commission` module. - Create and approve a new **Commission Plan**. - Click the **Commissions** button on the form view. - From the list view, click the **Details** button for a commission entry. - Observe the error. **Error:** `ValueError: Expected singleton: sale.commission.report()` Here, an error is triggered because the `action_achievement_detail` method at [1], expects a single `id` on the `sale.commission.report` record. However, when the commission report list loads, the `_table_query` method executes a SQL query - [2]. If any of `era.plan_id`, `u.user_id`, or `era.date_from` are **NULL**, the resulting id becomes `False`, which causes the singleton error when the user tries to open the details view. [1] - https://github.com/odoo/enterprise/blob/4575d3dfdbd0ccd9bf57bddbd35a89bd47c48798/sale_commission/model/commission_plan.py#L174-L175 [2] - https://github.com/odoo/enterprise/blob/4575d3dfdbd0ccd9bf57bddbd35a89bd47c48798/sale_commission/report/commission_report.py#L111 This commit produces a valid, non-null ID, preventing the downstream error. Sentry - 6587805735 Forward-Port-Of: odoo/enterprise#87304 Forward-Port-Of: odoo/enterprise#84785
In this commit: ------------ - We are fixing the unknown key "test" runbot error. runbot error-226611 Forward-Port-Of: odoo/enterprise#87482
Original PR description
In this commit: ------------ - We are fixing the unknown key "test" runbot error. runbot error-226611 Forward-Port-Of: odoo/enterprise#87482
#Description A total of 6 test were broken after changes(add/removal) in the accounts of the mexican localization in odoo community, the new expected values for the assesments were updated. Related PR #196852. Forward-Port-Of: odoo/enterprise#87238 Forward-Port-Of: odoo/enterprise#81270
Original PR description
#Description A total of 6 test were broken after changes(add/removal) in the accounts of the mexican localization in odoo community, the new expected values for the assesments were updated. Related PR #196852. Forward-Port-Of: odoo/enterprise#87238 Forward-Port-Of: odoo/enterprise#81270
42 changes
New functionality added to Odoo
Adds business planning documents covering platform features, pricing, onboarding, support, and go-to-market strategy for a proposed multi-tenant e-commerce offering. This helps align product, sales, and implementation teams before development begins.
Original PR description
This commit includes documentation outlining: - Core platform features. - 'Sweetener' features to attract small businesses. - Pricing and packaging models. - A high-level technical implementation approach, favoring Odoo. - User onboarding and support strategies. - Marketing and sales strategies. These documents provide a strategic foundation for the platform's development. 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
Enhancements to existing features
Accounting tax summaries can now group lines without taxes under a chosen category, such as exempt tax, instead of leaving them unclassified. This helps produce clearer totals and tax reporting in accounting, sales, and localized electronic invoicing flows.
Original PR description
At the moment, the tax aggregators always give a base line with no tax the `None` grouping key. Sometimes, we want base lines with no tax to be grouped as if they had a particular tax, such as an exempt one. This commit extends the aggregator behaviour so that for base lines with no tax, the grouping function is called with an empty tax_data dict, and the returned grouping key is used to group the base line. Enterprise PR: https://github.com/odoo/enterprise/pull/87223 task-4242065
Employees with flexible working schedules are no longer included in automatic check-out and absence management rules. This prevents attendance settings from incorrectly affecting people whose work hours are intentionally variable.
Original PR description
If the automatic check out and absence managment settings in attendance are set, it will not take into account the employees that have a flexible working schedule. These settings were not compatible with the notion of flexibility in hours. Backport of https://github.com/odoo/odoo/pull/196822 task-4816736
Untaxed invoice lines in Colombian and Mexican electronic invoicing can now be grouped using the appropriate tax category, such as exempt tax, instead of always being treated as uncategorized. This improves the accuracy of tax reporting and electronic invoice data for local compliance needs.
Original PR description
At the moment, the tax aggregators always give a base line with no tax the `None` grouping key. Sometimes, we want base lines with no tax to be grouped as if they had a particular tax, such as an exempt one. This commit extends the aggregator behaviour so that for base lines with no tax, the grouping function is called with an empty tax_data dict, and the returned grouping key is used to group the base line. Community PR: https://github.com/odoo/odoo/pull/213405 task-4242065
The Indian financial reports Balance Sheet now opens with the horizontal split option turned off by default. This makes the default report view simpler and avoids users needing to manually untick the option when they prefer the standard layout.
Original PR description
before this PR: split horizontally is ticked by default on Balance Sheet. after this PR: split horizontally is unticked by default. Task Id: 4836667
Duplicated Indian GST purchase records and related debit or credit notes will no longer carry over the original IRN number. This helps prevent the same official reference from appearing on multiple documents, reducing reporting confusion and compliance risk.
Original PR description
Before this PR: - IRN number was also copied when a record was duplicated or while creating a debit/credit note for purchase document. - This caused the same IRN to appear on multiple records. After this PR: - Now, when a record is duplicated or a debit/credit note is created, the IRN number will be empty to prevent duplication. Task Id: 4854568
Resolved issues and error corrections
This fixes cases where Odoo could send duplicate or inconsistently formatted Date headers in web responses, which created unnecessary warnings in server logs. It also standardizes date-related headers for generated editor images, helping caching behave more predictably without changing user-facing features.
Original PR description
Forward-port of https://github.com/odoo/odoo/pull/206505
This fixes an error that occurred when refunding Point of Sale orders containing multiple products valued with FIFO or average cost and processed with the ship later plus invoice option. Businesses can now complete these refunds without disruption, reducing checkout and back-office support issues.
Original PR description
When refunding a PoS order with mulitple lines containing a product with a category that use FIFO/AVCO valuation method, there was a traceback Steps to reproduce: ------------------- * Create a category CAT that use FIFO/AVCO valuation method * Create a product P1 with category CAT * Create a product P2 with category CAT * Create a PoS order with P1 and P2 * Validate the order using the shiplater and invoice option * Refund the order using the shiplater and invoice option > Observation: You get a traceback opw-4848667
This fix ensures Point of Sale buy X get Y promotions correctly increase the number of free items as customers add more qualifying products. It helps businesses apply loyalty rewards accurately at checkout and avoids under-delivering promised promotions.
Original PR description
When activating a loyalty program with a buy X get Y promotion. For example for buy 10 get 3, if you have 10 products in your cart and add 1 more product, it will add a reward for 1 free product. But if you add another product, the reward will stay the same, it will not give 2 free product. Steps to reproduce: ------------------- * Create a buy X get Y loyalty program (10 get 3 free) where X and Y are the same product. * Add 10 products to the cart. * Add 1 more product to the cart, it will add a reward for 1 free product. * Add another product to the cart > Observation: The reward will not change, it will still be 1 free product. Why the fix: ------------ If possible we will try to maximize the reward quantity. That's why we don't do it in cases where multiple rewards are possible. opw-4762083
Manufacturing unbuild operations no longer fail when a component move quantity is reduced. The fix keeps inventory valuation consistent by using the component cost from the original manufacturing order, even if prices changed later.
Original PR description
…nbuild **Problem:** When decreaseing the quantity of the stock move created for the component of the bom when unbuilding, it triggers an error message **Steps to reproduce:** - create a product…
…nbuild **Problem:** When decreaseing the quantity of the stock move created for the component of the bom when unbuilding, it triggers an error message **Steps to reproduce:** - create a product tracked by quantity (the "component product") - in the category field select an avco category - set an on hand quantity of 1 - create another product tracked by quantity (the "final product") - create a bom for this product and select your first product as the component - create a manufacture order for the final product - confirm and produce all - unbuild it and click on the "Unbuilds" smart button - select the line of the manufacture order - click on "product moves" - select the line of the component product - set the quantity to 0 **Current behavior:** an error message appears **Expected behavior:** a stock valuation layer should be created with the unit cost of the component product at the time of the manufacture order **Cause of the issue:** price_unit_map is created to make sure that when unbuilding a non standard final product, the outgoing stock valuation layer created for the final product has the same value as in the MO (the current standard_price could have changed due to POs since the MO happened for instance) https://github.com/odoo/odoo/blob/05cff3b7d866f6bc95c4b32f343ae14a4da946f2/addons/mrp_account/models/stock_move.py#L47-L56 when reducing the quantity of the stock move linked to the component of the unbuild an outgoing stock valuation layer is created and _get_out_svl_vals is triggered, those 2 conditions are true https://github.com/odoo/odoo/blob/05cff3b7d866f6bc95c4b32f343ae14a4da946f2/addons/mrp_account/models/stock_move.py#L55-L56 but the product is not the same as the one of move_finished_ids of the MO (this product is final product of the MO) so the filter result in an empty record set and [0] creates an index out of range error https://github.com/odoo/odoo/blob/05cff3b7d866f6bc95c4b32f343ae14a4da946f2/addons/mrp_account/models/stock_move.py#L49-L51 **Fix:** the unit_cost of the stock valuation layer for the component product created from unbuild is the same as : the unit_cost from the stock valuation layer created from the MO for the component (even if the standard_price changed inbetween). https://github.com/odoo/odoo/blob/4fd9ae6ccd96ac13475e7e5aa9805e6f529cd609/addons/stock_account/models/stock_move.py#L516-L517 https://github.com/odoo/odoo/blob/4fd9ae6ccd96ac13475e7e5aa9805e6f529cd609/addons/stock_account/models/stock_move.py#L51 So to be consistent an ajustement to the the stock move created from the unbuild should create a stock valuation layer which also has the same unit cost opw-4747920
This fix prevents payment status updates from failing when multiple accounting accounts share the same type. It improves reliability for accounting workflows by correctly checking reconciliation status across all relevant accounts.
Original PR description
Issue: Before this commit, sometimes we might have different accounts with the same type, which throws a singleton error Fix: Check if all the accounts are not reconciled oes-4798698
This fix makes the Accounting area check that a menu item exists before including it in results. It prevents unnecessary errors when a menu is unavailable, helping users continue working without interruption.
Original PR description
Check that the menu actually exists before adding it to the results. Also don't raise error if not found. 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
This update makes an automated test for image transformation more stable, reducing random failures in Odoo's validation process. It helps developers get more reliable test results without changing how users interact with the HTML editor.
Original PR description
Purpose of this PR: - The image transformation test was failing non-deterministically on runbot due to bare `expect(...).toHaveCount` calls. This commit replaces them with the `expectElementCount` utility. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents employees with flexible schedules from being marked absent when they had approved leave. It corrects day-end time handling and avoids counting tiny timing differences as work or overtime, improving accuracy in attendance and leave records.
Original PR description
### Steps to reproduce: - Enable Absence Management from general settings - Create a leave for the previous day for a flexible employee - Run the 'Detect Absences for employees' cron job - Navigate…
### Steps to reproduce: - Enable Absence Management from general settings - Create a leave for the previous day for a flexible employee - Run the 'Detect Absences for employees' cron job - Navigate to the attendance gantt view - Notice a negative attendance created for the employee on the day of his leave ### Cause: This is happening because when checking the expected attendances for a flexible employee there is a difference between the end of the attendance interval (e.g. 2025-04-03 00:00:00 UTC) and the of the leave interval (e.g. 2025-04-02 23:59:59.9999 Europe/Burssels). This difference considered to be an expected attendance. Also when checking the attendances to calculate working hours and overtime duration we take the attendance created to cover the absence into account and assume that it is working hours https://github.com/odoo/odoo/blob/6beb3ea82d75513803ae78f5bc71024313938a97/addons/hr_attendance/models/hr_attendance.py#L357-L366 ### Fix: We are now setting the end datetime of the attendance interval to be the end of the day in the user's timezone not in UTC. Also set the end of the leave interval to be the minimum time of the next day instead of the max time in the same day of the leave. Also when calculating the overtime duration for flexible employee we check if it is a very small amount of time. opw-4545023
This fixes downloads for files whose extensions include an underscore, such as Parasolid .x_t files. Odoo will now preserve the original filename instead of adding an extra .txt extension, reducing confusion for users sharing or retrieving documents.
Original PR description
Step to reproduce; - install documents - upload a parasolid file, it has extension `x_t` - download it Observation: if a file is uploaded with file named as `file.x_t`, it will be downloaded as `file.x_t.txt` Issue: currently, the `get_extension` method only allow alphanumeric values for extension, which do not consider extension having '_' https://github.com/odoo/odoo/blob/15fd3f62769b137cb9a0625f47b333424b851a27/odoo/tools/mimetypes.py#L212-L218 when such file is downloaded, `_get_stream_from` appends extra extension to the filename, depending upon its mimetype. https://github.com/odoo/odoo/blob/15fd3f62769b137cb9a0625f47b333424b851a27/odoo/addons/base/models/ir_binary.py#L148-L150 Fix: instead of `isalnum()`, use a regex that allows alphanumeric and underscore in extension. opw-4801263 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Italian electronic invoices now include cash rounding adjustments in the total amount shown in the exported XML. This prevents mismatches between the invoice total and the official XML, supporting compliance with Italian fiscal rules for cash payments.
Original PR description
The Italian Law requires cash payments to be rounded up to 5 cents (art. 13 del D.Lgs. 231/2007, updated in 2018). The exported XML invoice didn't have any cash rounding lines and so the sum was wrong in ImportoTotaleDocumento. This was happening because cash rounding lines (`display_type == 'rounding'`) were excluded during the export function's computation.
This fix makes the function include `rounding` lines into the computation, making the invoice compliant.
Steps:
1. Activate cash rounding management.
2. Create a `0.05E` cash rounding.
3. Create an invoice with a total that is not rounded.
4. Set up the cash rounding on the invoice:
Other information > Cash rounding method
An invoice cash rounding line will be created, the total will be rounded.
5. Generate the XML and download it.
6. The amount in `ImportoTotaleDocumento` tag will not match the total of the invoice.
Task [link](https://www.odoo.com/odoo/project/967/tasks/4816355)
task-4816355Sales users without stock permissions can now access the forecast report from sales documents instead of seeing an access error. They can view the information needed for customer commitments, while stock reservation actions remain restricted to users with the right inventory permissions.
Original PR description
Task: 4640948 Currently, a sales user with no stock permissions can see the little forecast icon and, upon clicking on it, a link to the forecast report. However, trying to access the report results in an "Access Error" message. The forecast report is important for sales users. This commit will allow them to access the report, but without the option to edit stock pickings (reserve/unreserve buttons). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Returned products that were not part of the original sale are now placed after existing sales order lines instead of appearing in the middle of the order. This keeps sales orders easier to read and avoids confusion when reviewing returns involving replacement or different products.
Original PR description
Issue ----- When returning different products than the ones sold on the SO, the returned products have their sequence set to 10 so they all appear between the first and second sold products. Steps to reproduce ----- - Install both Sale & Stock apps - Create & confirm a sale for 2 different products - Confirm the delivery - Create & validate a return for a third product - Open the SO -> The returned product sol is second in sequence Cause ----- The return SOL are created with no specified sequence value, so they all have the default (10). See [review](https://github.com/odoo/odoo/pull/209091#pullrequestreview-2828126823) for details. ----- Ticket: opw-4564504
Posting an invoice or bill will now only automatically mark it as checked when the related journal is configured to do so. This prevents a user’s existing checked status from being unintentionally cleared during posting, helping preserve review decisions and reduce accounting errors.
Original PR description
Description of the issue/feature this PR addresses: Posting an account move will unconditionally overwrite any value in the `checked` field to the value of the `journal_id.autocheck_on_post` field. I.e. whatever the user has selected in the `checked` will be overwritten. This PR will change the functionality to work as the original comment for the feature states. Current behavior before PR: The `checked` field on an account move is always updated to the value of the `journal_id.autocheck_on_post` field, when posting an account move. Desired behavior after PR is merged: The checked field on an account move is updated to the value of the journal_id.autocheck_on_post, when posting a move, only when the journal_id.autocheck_on_post is `True`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The slide sharing dialog now explains that email shares may be sent later because messages are queued and processed in batches. This avoids confusing users into thinking the share failed and helps prevent duplicate email sends.
Original PR description
This PR updates the share dialog message shown when a slide is shared via email. Since emails are queued and sent later in batches, the previous message could be misleading and prompt users to send multiple emails unnecessarily. Task-4797324
Manufacturing work order time entered through the work order widget now updates project analytic accounts with the correct labor cost. This prevents misleading gross margin figures caused by near-zero or incorrect cost entries.
Original PR description
…rrect data from MO operation **Problem:** lines of mrp.workcenter.productivity added from the workorder widget do not update the linked analytic account with the right amount **Steps to reproduce:**…
…rrect data from MO operation **Problem:** lines of mrp.workcenter.productivity added from the workorder widget do not update the linked analytic account with the right amount **Steps to reproduce:** - enable "analytic accounting" setting - Unarchive MTO route - Create a new product - In the inventory page check MTO and Manufacture routes - click on the Bill of materials smart button and create a new BOM - add a component and an operation - Create another product, set "product type" as service - in the "create on order" field select "project & task" - create a new quotation with these two products and confirm - click on the "manufacturing" smart button - in the work orders page click on the "open work order" button at the right of the line - click on add a line - set a duration of 30:10 and clik elsewhere on the screen - save - click on the "analytic account" smart button - select the only line and click on the "gross margin" smart button **Current behavior:** There is a single line with an amount of 0.01 **Expected behavior:** The price should reflect the hourly rate of the employee for the task (that's 50.28 with a 100$/hours rate for instance) **Cause of the issue:** There is two issue here. First Issue : When clicking on save on the widget, this will modify the time_ids field of the mrp.workorder this will create a new mrp.workcenter.productivity with the values we wrote. Consequently, on the vals_list when the create method is triggered duration is set to the duration we wrote (so here 30.17) Because of this, when the _compute_duration is the triggered previous_durations will be [30.17] and _create_analytic_entry will be called with a parameter of 30.17 https://github.com/odoo/enterprise/blob/8a21b4f8ee8d24ebbc9ac2eb08696a0de056357f/project_mrp_workorder_account/models/mrp_workcenter_productivity.py#L10-L14 Therefore, inside _create_analytic_entry duration will be 0 and amount will also be 0 This issue does not happen if the duration is set by changing the "real duration" in the "work orders" page of the manufacturing order. This is because when doing it this way, we modify the duration of the mrp.workorder which triggers the set_duration_method which also creates a new mrp.workcenter.productivity but here the _prepare_timeline_vals returns a dictonary without a duration field https://github.com/odoo/odoo/blob/4fe90167266a92c3a5941eac9a6a2084a80056ac/addons/mrp/models/mrp_workorder.py#L352-L353 Second Issue: The line we see with a 0.01 amount is actually created before we save. It's created from the onchange method when we change the duration on the form. The onchange of duration triggers an onchange of start date which gets the value of duration and triggers of recomputation of duration https://github.com/odoo/odoo/blob/4fe90167266a92c3a5941eac9a6a2084a80056ac/addons/mrp/models/mrp_workcenter.py#L522-L531 As a consequence, _compute_duration is called. self.duration is initially not rounded so in our exemple previous duration will be equal to 30.1666666666668 https://github.com/odoo/enterprise/blob/8a21b4f8ee8d24ebbc9ac2eb08696a0de056357f/project_mrp_workorder_account/models/mrp_workcenter_productivity.py#L10-L11 However after the call to super()._compute_duration(), self.duration will be rounded thanks to the use of convert to duration inside the super method https://github.com/odoo/odoo/blob/4fe90167266a92c3a5941eac9a6a2084a80056ac/addons/mrp/models/mrp_workcenter.py#L472 So when doing the difference here inside _create_analytic_entry https://github.com/odoo/enterprise/blob/8a21b4f8ee8d24ebbc9ac2eb08696a0de056357f/project_mrp_workorder_account/models/mrp_workcenter_productivity.py#L38 duration will be 5.555555555556424e-05 and amount will be -0.005555555555556424 which results in the creation of this line with an amount of 0.01 **fix:** Calling the creation of account.analytic.line from the compute method leads to other problems : For instance, if a line is added in the "open work order" widget and we change the end date but change our mind and don't save the line, the duration will have been computed and a new account analytic line will have been created Whereas calling the method _create_analytic_entries from create() and write() ensures it's only called when the model is saved opw-4715690
This fix prevents payroll pivot reports from failing when a custom salary rule field without a country code is added through Studio. Businesses can now use these custom payroll measures in reporting without encountering an error.
Original PR description
**Steps to reproduce:** 1. Install hr_payroll. 2. Create a salary rule (with a structure where country_id is null) and set `View on Payroll Reporting?` is checked for a custom field (x_l10n_xx_%). 3. Add the custom field to the payroll report's pivot view using Studio. **Issue:** - The pivot view fails to open, resulting in a traceback. ``` UncaughtPromiseError > OwlError Uncaught Promise > The following error occurred in onWillStart: "Cannot read properties of undefined (reading 'string')" ``` **Cause:** - Custom field that not start with `l10n_<country_code>` or `x_l10n_<country_code>` are removed, causing undefined fields in the pivot view. https://github.com/odoo/enterprise/blob/ccb5ed4779db4bdf6944f43eb2e4a7aa978b9272/hr_payroll/static/src/js/hr_payroll_report_pivot_model.js#L13-L15 **Solution:** - Allow to add custom fields created from salary rules without a country code to be used as custom measures in the pivot view. opw-4688376
Changing a sales quotation template from one with a recurring plan to one without now correctly clears the recurring plan field. This prevents outdated subscription plan information from remaining on sale orders and helps users avoid incorrect subscription setup.
Original PR description
**Issue:** - In sale order, first select the quotation template with a recurring plan, then, change the quotation template to without a recurring plan. After changing the quotation template, the…
**Issue:** - In sale order, first select the quotation template with a recurring plan, then, change the quotation template to without a recurring plan. After changing the quotation template, the 'Recurring Plan' (`plan_id`) field still shows the value from the previously selected template. This happens because the `plan_id` is not reset when the new template has no recurring plan. - In version 17, this case was handled in the else part and set [default value](https://github.com/odoo/enterprise/blob/17.0/sale_subscription/models/sale_order.py#L490) (company_id.subscription_default_plan_id), but in version 18.0, the field was [removed](https://github.com/odoo/enterprise/pull/55355/files). **Steps to reproduce:** - Install the Sales and Subscriptions modules. - Create two quotation templates — one with a recurring plan and one without. - Create a Sale Order and first select the quotation template 'with a recurring plan'. - Then, change the quotation template to 'without a recurring plan'. **Solution:** - Reset `plan_id` to `None` before computing the new value to ensure accurate computation. If the selected quotation template has a recurring plan, it will be assigned; otherwise, the plan_id field will remain empty. **Runbot v18.0 (without fix)**   OPW: [4845478](https://www.odoo.com/odoo/70/tasks/4845478)
Creating a payslip for Belgian employees could fail when a work entry covered a long period, such as a full month. This fix ensures those long work entries are handled correctly so payroll processing can continue without errors.
Original PR description
There is a bug in the module that made the creation of payslip triggers an error. Steps to reproduce it :
1) Use a Belgian company and an employee with a contract;
2) Create a work entry for a whole month (from 05/01/2025 09:00:00 to 06/01/2025 17:00:00 for example);
3) Try to create a payslip for this employee.
Error :
File "/data/build/enterprise/l10n_be_hr_payroll/models/hr_contract.py", line 517, in _get_work_hours_split_half
work_data[('half', work_entry.work_entry_type_id.id)] += dt.days * 24 + dt.seconds / 3600 # Number of hours
TypeError: 'float' object is not iterable
[opw-4752109](www.odoo.com/odoo/project/49/tasks/4752109)Users can now upload a file to a document request successfully the first time they try. This removes a frustrating retry step and makes document collection smoother and more reliable.
Original PR description
Before this commit, when one tries to upload a file to a document request for the first time it does nothing.
This is caused by an async memoize call which causes the file to be cleared between the memoize rpc call and the file processing after that call... After that first call the user can upload a new file without issue but it's still annoying.
This commit fix this issue by storing the file in a variable before doing the memoize rpc call.
Task-4778429Hong Kong payroll tax report exports no longer fail when a married employee has no spouse name recorded. This allows businesses to generate required IRD reports from confirmed payslips without needing unnecessary placeholder spouse details.
Original PR description
Steps: - Create an employee with marital status is married - Keep the spouse name empty - Try to export ird reports with a confirmed payslip Current behavior: - Error raised Expected behavior: - Should be able to export the report even spouse name is empty
This fix prevents users from clearing or editing currency settings in Studio when doing so would cause an error. It keeps monetary fields stable while users customize list views, reducing failed saves and support issues.
Original PR description
Currently an error occurs when the user tries to remove the currency on any monetary field through web studio.
Steps to replicate:
- Open any list view with web_studio.
- Drag and drop a monetary field and remove the currency field and save.
Error:
`TypeError: Argument must be bytes or unicode, got 'NoneType'`
This error occurs because the `attrs` dictionary contains `{'name': None}`, and `etree.Element()` doesn't accept attributes with None values, causing it to raise a `TypeError`.
This commit fixes the issue by making the field required so that user cant remove the value from currency field and hence preventing error at line [1].
[1]-https://github.com/odoo/enterprise/blob/a41cca06bc1e25614390f9207c937566557350a0/web_studio/controllers/main.py#L928
sentry-4244801243Importing bank statement lines from CSV now preserves an included statement reference instead of always creating a new bank statement. This prevents duplicate statements and keeps imported reconciliation data tied to the correct existing statement.
Original PR description
…id during import In the override of execute_import of account_bank_statement_import_csv.py a new account.bank.statement was always created even if the import contained statement_id. Steps to reproduce: - Export an account.bank.statement.line in bank rec with the statement_id included. - Import it back. The statement_id of the imported lines is a new one. opw-4753864
Miscellaneous changes
The tax breakdown is required by Argentinian law to be displayed in the bottom left corner of the invoice report. This was added in [^1] and works well for the HTML view but min-width related classes don't work well with pdf rendering, so the table stretched across the entire width of the pdf. The fix is to follow the rest of the file and use a fixed col width on the table for the pdf view. task-4779975 [^1]: https://github.com/odoo/odoo/pull/201257 Forward-Port-Of: odoo/odoo#214463
Original PR description
The tax breakdown is required by Argentinian law to be displayed in the bottom left corner of the invoice report. This was added in [^1] and works well for the HTML view but min-width related classes don't work well with pdf rendering, so the table stretched across the entire width of the pdf. The fix is to follow the rest of the file and use a fixed col width on the table for the pdf view. task-4779975 [^1]: https://github.com/odoo/odoo/pull/201257 Forward-Port-Of: odoo/odoo#214463
When calculating line discounts, extra decimal places are being used when computing the total in intermediate steps. This discrepancy is interpreted as a small discount, that shouldn't be there. We should instead use the current currency's precision. Example: ``` qty: 1.65 unit_price: 29.9 total: 1.65 * 29.9 = 49.335, rounded to 49.34 discount = 0.005 * 100 / 49.335 = 0.010 ``` Steps: - Create an invoice with a product - Set quantity to 1.65, price to 29.9 - Confirm & get the invo
Original PR description
When calculating line discounts, extra decimal places are being used when computing the total in intermediate steps. This discrepancy is interpreted as a small discount, that shouldn't be there. We should instead use the current currency's precision. Example: ``` qty: 1.65 unit_price: 29.9 total: 1.65 * 29.9 = 49.335, rounded to 49.34 discount = 0.005 * 100 / 49.335 = 0.010 ``` Steps: - Create an invoice with a product - Set quantity to 1.65, price to 29.9 - Confirm & get the invoice PDF - Upload the PDF in accounting app - Check the "discount" value Slight improvement to odoo/odoo#206107 opw-4776391 Forward-Port-Of: odoo/odoo#211032
<b>Steps to Reproduce:</b> 1. Navigate to Sales → Products → Products. 2. Click on Print Labels. 3. Select label format 2×7. 4. Add an image to the "Extra Content" field (e.g., by typing `/image`). <b>Issue:</b> - When printing labels, the image added via `extra_html` is not fully displayed. It gets cut off due to the fixed height and overflow settings on the `.o_label_extra_data` container. <b>Solution:</b> - Added responsive styling to o_label_extra_data for img so they resize pr
Original PR description
<b>Steps to Reproduce:</b>
1. Navigate to Sales → Products → Products.
2. Click on Print Labels.
3. Select label format 2×7.
4. Add an image to the "Extra Content" field (e.g., by typing `/image`).
<b>Issue:</b>
- When printing labels, the image added via `extra_html` is not fully displayed. It gets cut off due to the fixed height and overflow settings on the
`.o_label_extra_data` container.
<b>Solution:</b>
- Added responsive styling to o_label_extra_data for img so they resize properly and stay within bounds:
```css
.img {
max-height: 2.5em;
max-width: 100%;
}
```
ensures image appear without being cropped.
<b>opw-4741550</b>
Before FIX:

After FIX:

Forward-Port-Of: odoo/odoo#212903Write some bytes in a `field.Binary(attachment=False)` field. The ORM doesn't encode the bytes in b64, and the value is stored as a binary blob in postgres. Attempt to download the content via /web/content (actually any route that uses `http.Stream` is affected). It sometimes download something, sometimes fail with an "Incorrect padding" error. The `http.Stream` class wrongly assumes that reading a binary/image field is always going to return the value base64-encoded, thus it always attemp
Original PR description
Write some bytes in a `field.Binary(attachment=False)` field. The ORM doesn't encode the bytes in b64, and the value is stored as a binary blob in postgres. Attempt to download the content via…
Write some bytes in a `field.Binary(attachment=False)` field. The ORM doesn't encode the bytes in b64, and the value is stored as a binary blob in postgres. Attempt to download the content via /web/content (actually any route that uses `http.Stream` is affected). It sometimes download something, sometimes fail with an "Incorrect padding" error. The `http.Stream` class wrongly assumes that reading a binary/image field is always going to return the value base64-encoded, thus it always attemps to decode it. The `b64decode` function silently discard non-b64 characters and only complain if the final thing lacks the b64 `=` padding (to make the length a multiple of 4). So when it downloaded something, it downloaded crap. Makes the code actually raise an error should the binary field not contains b64 data. Fixing the problem by using the data as-is (with no b64 decoding) is not desirable. We use `Binary(attachment=False)` when we need to store sensitive documents, often cryptographic keys, and exporting them is often not desirable. 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#214340 Forward-Port-Of: odoo/odoo#213997
Backport of e21ff0ed57574694e75ef2b4f4e2e41f8bb0412a Manager of an employee could only approve a Time Off request Steps to reproduce: ------------------- * Revoke Marc Demo's Time Off Access Rights in Settings * Assign Marc Demo as manager to an employee * Create a New Time Off request for that employee * Log in as Marc Demo * Head to Time Off > Management > Time Off > Observation: The request can only be approved. Time Off Access Rights' tooltip specifiy that `A user without an
Original PR description
Backport of e21ff0ed57574694e75ef2b4f4e2e41f8bb0412a Manager of an employee could only approve a Time Off request Steps to reproduce: ------------------- * Revoke Marc Demo's Time Off Access Rights in Settings * Assign Marc Demo as manager to an employee * Create a New Time Off request for that employee * Log in as Marc Demo * Head to Time Off > Management > Time Off > Observation: The request can only be approved. Time Off Access Rights' tooltip specifiy that `A user without any rights on Time Off will be able to see the application, create his own holidays and manage the requests of the users he's manager of.` opw-4725537 Forward-Port-Of: odoo/odoo#213292
- The "Clear" button is only accessible by "group_stock_manager" but without a group attached, "stock_user" can still see it and operate it, resulting in an unnecessary permission error, confusing the user. Current behavior before PR:  
Original PR description
- The "Clear" button is only accessible by "group_stock_manager" but without a group attached, "stock_user" can still see it and operate it, resulting in an unnecessary permission error, confusing the user. Current behavior before PR:   --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213508
The "Alert Date Reached" activity was not correctly assigning the activity to the "Default User" specified in the `mail.activity.type` settings. This did not align with user expectations that the activity type's default user should be primarily considered. To reproduce the issue: 1. Configure a "Default User" (e.g., User A) for the Alert Date Reached activity type. 2. Create a product tracked by lots. Ensure its "Responsible User" (on the product's Inventory tab) is either not set or is a d
Original PR description
The "Alert Date Reached" activity was not correctly assigning the activity to the "Default User" specified in the `mail.activity.type` settings. This did not align with user expectations that the…
The "Alert Date Reached" activity was not correctly assigning the activity to the "Default User" specified in the `mail.activity.type` settings. This did not align with user expectations that the activity type's default user should be primarily considered. To reproduce the issue: 1. Configure a "Default User" (e.g., User A) for the Alert Date Reached activity type. 2. Create a product tracked by lots. Ensure its "Responsible User" (on the product's Inventory tab) is either not set or is a different user (e.g., User B). 3. Receive the product with a lot number and set its alert date to be in the past. 4. Trigger the scheduler for checking lot expirations (via Operations > Run Scheduler). 5. The generated "Alert Date Reached" activity would be assigned to User B (if set) or the superuser, incorrectly ignoring User A. This commit rectifies this behavior by modifying the user assignment logic for these lot expiry alerts. The new priority for determining the assignee is: 1. The "Default User" configured on the "Alert Date Reached" activity type. 2. If no default user is set on the activity type, then the "Responsible User" defined on the related product. 3. If neither is set, the activity is assigned to SUPERUSER. [opw-4640027](https://www.odoo.com/odoo/project.task/4640027) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#212154
### Steps to reproduce: - Install PoS mexican localization - Navigate to PoS and create an order with a discount line - Go to back end and try to refund this order - Notice an error pops-up ### Cause: This is happening because when refunding an order we are checking if every line has positive price but since discount lines will have negative value it trigger the validation error. https://github.com/odoo/enterprise/blob/78bcd2e0b9296ad124ea1c3157a884fa6e62999a/l10n_mx_edi_pos/model
Original PR description
### Steps to reproduce: - Install PoS mexican localization - Navigate to PoS and create an order with a discount line - Go to back end and try to refund this order - Notice an error pops-up ### Cause: This is happening because when refunding an order we are checking if every line has positive price but since discount lines will have negative value it trigger the validation error. https://github.com/odoo/enterprise/blob/78bcd2e0b9296ad124ea1c3157a884fa6e62999a/l10n_mx_edi_pos/models/pos_order.py#L286 ### Fix: We check if the order lines are positive but after filtering the discount lines out opw-4528737 Forward-Port-Of: odoo/enterprise#84331
**Version:** 16.0 **Steps to reproduce:** - Install industry_fsm_sale - Create two tasks without linking them to a Sale Order - Go to list view and select those tasks - Click "Create Invoice" **Issue:** When the user selects tasks from the list view that are not linked to any Sale Order and tries to create an invoice, a traceback occurs. **Cause:** At least one linked Sale Order record is required when generating an invoice. If the selected tasks are not associated w
Original PR description
**Version:**
16.0
**Steps to reproduce:**
- Install industry_fsm_sale
- Create two tasks without linking them to a Sale Order
- Go to list view and select those tasks
- Click "Create Invoice"
**Issue:**
When the user selects tasks from the list view that are not linked to any Sale Order and tries to create an invoice, a traceback occurs.
**Cause:**
At least one linked Sale Order record is required when generating an invoice. If the selected tasks are not associated with any Sale Order, the process fails.
**Fix:**
This commit raise a red toast notification if none of the selected tasks are linked to a Sale Order. This helps the user understand the issue and prevent traceback..
task-4594178`
Forward-Port-Of: odoo/enterprise#87606
Forward-Port-Of: odoo/enterprise#83661Steps to reproduce: 1. Install the german localization 2. Create company in DE 3. Create a partner that has country = PL 4. Create a customer invoice for the PL partner 5. Open: Accounting > Reporting > EC Sales List 6. Hit the wheel and create the CSV export. 7. Open the file Issue: see that the amount is a float Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4575788) opw-4575788 Forward-Port-Of: odoo/enterprise#87421 Forward-Port-Of: odoo/enterprise#83822
Original PR description
Steps to reproduce: 1. Install the german localization 2. Create company in DE 3. Create a partner that has country = PL 4. Create a customer invoice for the PL partner 5. Open: Accounting > Reporting > EC Sales List 6. Hit the wheel and create the CSV export. 7. Open the file Issue: see that the amount is a float Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4575788) opw-4575788 Forward-Port-Of: odoo/enterprise#87421 Forward-Port-Of: odoo/enterprise#83822
opw-4772870 opw-4664501 Forward-Port-Of: odoo/enterprise#86891
Original PR description
opw-4772870 opw-4664501 Forward-Port-Of: odoo/enterprise#86891
When generating the accounting entry from the Corporate Tax Report, the system first tries to find a miscellaneous journal with the short code `MISC`. If this specific journal does not exist, the logic attempts to fall back and find any other journal of type 'Miscellaneous' (`type = 'general'`). However, this fallback search fails with an error due to an incorrect search domain syntax. Steps to reproduce: 1. Go to Accounting > Configuration > Journals. 2. Ensure no journal exists with th
Original PR description
When generating the accounting entry from the Corporate Tax Report, the system first tries to find a miscellaneous journal with the short code `MISC`. If this specific journal does not exist, the logic attempts to fall back and find any other journal of type 'Miscellaneous' (`type = 'general'`). However, this fallback search fails with an error due to an incorrect search domain syntax. Steps to reproduce: 1. Go to Accounting > Configuration > Journals. 2. Ensure no journal exists with the short code MISC. 3. Ensure at least one other journal of type "Miscellaneous" exists (for example, with short code GEN or MSC). 4. Go to Accounting > Reporting > Corporate Tax Report. 5. Try to generate the accounting entry. opw-4836686 Forward-Port-Of: odoo/enterprise#87300
Currently, a raceback occurs when the user changes or adds the expression label of the column in the "Generic Tax report". **To reproduce this issue:** 1) Install "account_reports" 2) Open "Generic Tax report" from "Accounting Reports" 3) In columns change the "Expression Label" and save the record 4) Open the "Tax Report" in "Reporting" 5) A traceback occurs **Error:** ``` UnboundLocalError: local variable 'col_value' referenced before assignment ``` **Cause:** The "co
Original PR description
Currently, a raceback occurs when the user changes or adds the expression label of the column in the "Generic Tax report". **To reproduce this issue:** 1) Install "account_reports" 2) Open "Generic Tax report" from "Accounting Reports" 3) In columns change the "Expression Label" and save the record 4) Open the "Tax Report" in "Reporting" 5) A traceback occurs **Error:** ``` UnboundLocalError: local variable 'col_value' referenced before assignment ``` **Cause:** The "col_value" is assigned based on the "expr_label" if it doesn't match the if conditions it leads to a traceback. https://github.com/odoo/enterprise/blob/d154cbf1bd5b4cc104ff0e2443047aff0c05330f/account_reports/models/account_generic_tax_report.py#L921-L932 **Solution:** This commit will resolve this issue by assigning a fallback value of an empty string to col_value. opw-4841789 Forward-Port-Of: odoo/enterprise#87277
Currently, an error is produced when the payslip start date is not set, but the end date is provided. **Steps to reproduce:** - Install `hr_payroll` module(with demo). - Create new **Payslip** for employee **Anita Oliver**. - Clear both the start and end dates under the "Period" section. - Set only the end date. **Error:** `TypeError: '<' not supported between instances of 'bool' and 'datetime.date'` **Cause:** The `_compute_warning_message` method performs a comparison between `s
Original PR description
Currently, an error is produced when the payslip start date is not set, but the end date is provided. **Steps to reproduce:** - Install `hr_payroll` module(with demo). - Create new **Payslip** for…
Currently, an error is produced when the payslip start date is not set, but the end date is provided. **Steps to reproduce:** - Install `hr_payroll` module(with demo). - Create new **Payslip** for employee **Anita Oliver**. - Clear both the start and end dates under the "Period" section. - Set only the end date. **Error:** `TypeError: '<' not supported between instances of 'bool' and 'datetime.date'` **Cause:** The `_compute_warning_message` method performs a comparison between `slip.date_from` and `contract_id.date_start` without verifying if `date_from` is set. When `date_from` is `False`, the comparison `False < datetime.date(...)` - [1], raises a `TypeError`. [1] - https://github.com/odoo/enterprise/blob/a65314702b99df97c778d4f12f943191a19dafd1/hr_payroll/models/hr_payslip.py#L1029-L1031 This commit adds checks to ensure that start and end date is defined before performing date comparisons in warning message computation, preventing the error. Sentry - 6618275041 Forward-Port-Of: odoo/enterprise#86091