Daily updates from Odoo
Tuesday, June 16, 2026
40 changes · saas-19.1
Enhancements to existing features
This update automatically populates the company registry information in Odoo for Swedish businesses using their VAT number. Swedish VAT numbers always start with 'SE' followed by digits, and this change leverages this pattern to streamline data entry. This improves accuracy and reduces manual effort for users operating in the Swedish market.
Original PR description
Organization number is part of the VAT number Official reference: https://www.skatteverket.se/foretag/moms/kopavarorochtjanster/inkopfranandraeulander/kopavarorfranandraeulander.4.3a7aab801183dd6bfd380005738.html > I Sverige börjar alla VAT-nummer med bokstäverna SE (landskoden) och avslutas med siffrorna 01. Om du har en enskild firma följs landskoden av de 10 siffrorna i ditt personnummer. Om du har ett bolag eller en förening följs landskoden av de 10 siffrorna i organisationsnumret. VAT-numret skrivs utan bindestreck. which translates to > In Sweden, all VAT numbers begin with the letters SE (the country code) and end with the digits 01. If you are a sole proprietor, the country code is followed by the 10 digits of your personal identification number. If you are a corporation or an association, the country code is followed by the 10 digits of your organization number. The VAT number is written without a hyphen. Forward-Port-Of: odoo/odoo#269590
This update integrates with the new Gmail Chrome and Firefox extension to automatically capture email data (sender, recipients, etc.) related to timesheet activity. Odoo then uses this information to provide more relevant suggestions and tracking for timesheets, improving project management insights.
Original PR description
[IMP] timesheet_grid: Gmail watcher In this commit, Odoo now consumes data from the new Gmail Chrome and Firefox web extension, which captures the from, to, cc, and bcc fields of read and composed emails and sends them to Activity Watch. Odoo retrieves these events, extracts the emails, searches for partners linked to projects and/or tasks, and adds them to suggestions as keyEvents. task-5956040
This update ensures that all user-provided descriptions for invoice lines are accurately exported in UBL format. Previously, the system only supported a single description tag, but this change now correctly handles multiple descriptions, preventing data loss and improving the accuracy of UBL invoices.
Original PR description
1) Previously, we were supposing that only one <cbc:Description> tag could be found on InvoiceLine item. After checking the UBL XSD, I found we could have multiple Description tags for one item. 2) The import order of <cbc:Name> and <cbc:Description> on the invoice line now has been changed to be more accurate and prevent loss of information. The export has been adapted to this change too. Now, we export the actual description written by the user. task-6153895 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261949
Resolved issues and error corrections
This update corrects a bug where submitting the Contact Us form incorrectly updated both the task and project customer records. The fix ensures that task customer information is correctly linked to the newly created project, preventing unintended data duplication and maintaining accurate customer relationships. This improves data consistency and reliability.
Original PR description
Steps to reproduce: -------------------------------------------- 1. Install `website_project` module 2. Create a new project 3. Add a customer to the project 4. Go to customer > add email and phone…
Steps to reproduce:
--------------------------------------------
1. Install `website_project` module
2. Create a new project
3. Add a customer to the project
4. Go to customer > add email and phone
5. Create a new task in that project:
* Observe that the customer is the same as the project
6. Go to Website > Contact Us > Edit > Click on submit button
7. Set action to 'Create a Task' and select the created project in 'Project'
8. Click on Save and Open the URL in Incognito Mode
9. Go to the Contact Us page > Fill in the details > Submit
10. Comeback to our window and open tasks of the created project
Observation:
--------------------------------------------
1. A new task is created using the customer details entered in the form.
2. The existing task’s customer and the project’s customer are also incorrectly updated to this new customer.
Issue:
--------------------------------------------
The bug is in the `extract_data` method of the website form controller for projects.
A non-logged-in user submits the Contact Us form with name and an email that doesn't match any existing partner. The old code's `else` branch would set `partner_name` in the task record values without setting a `partner_id` https://github.com/odoo/odoo/blob/cd080047578b9992811608a5af73a982a414da39/addons/website_project/controllers/main.py#L65-L66
During task creation, the computed field `_compute_partner_id` automatically sets `partner_id` to the project's partner
https://github.com/odoo/odoo/blob/cd080047578b9992811608a5af73a982a414da39/addons/project/models/project_task.py#L1440-L1441
`partner_name` is defined as
https://github.com/odoo/odoo/blob/cd080047578b9992811608a5af73a982a414da39/addons/website_project/models/project_task.py#L12
In Odoo, a related field is essentially a shortcut to a field on a linked record The key attribute here is `readonly=False`. This tells Odoo:
* On read: Get the value from `self.partner_id.name`
* On write: Propagate the write back to `self.partner_id.name` (this is the inverse). So writing `task.partner_name = 'TEST'` is equivalent to writing `task.partner_id.name = 'TEST'`. It modifies the partner record itself, not just the task.
So, the partner record itself was renamed. Every record that references a partner now sees the new name
Solution:
--------------------------------------------
The fix passes `False` to `partner_id`, this way:
* The existing partner is untouched
* All other tasks and the sales order keep their correct customer
opw-6206080
Forward-Port-Of: odoo/odoo#264738This update resolves an issue where the barcode inventory count feature would fail when using archived units of measure. The fix ensures that archived UOMs are correctly included in the inventory count cache, allowing users to accurately count stock even when units have been archived. This improves the reliability of inventory adjustments.
Original PR description
### Steps to reproduce: - In the settings enable: "Units of Measure & Packagings", "Storage Locations" - Create a product in units and register 1 unit in stock - Inventory > Operations > Adjustments…
### Steps to reproduce: - In the settings enable: "Units of Measure & Packagings", "Storage Locations" - Create a product in units and register 1 unit in stock - Inventory > Operations > Adjustments > Physical Inventory - Select your line and request a count > Set Current Value - Inventory > Configurations > units of measures > UOM categories - Select unit and archive it - Go to the barcode app > Click Count inventory ### > Owl error: Uncaught promise ### Cause of the issue: Since the uom used on the quant is archived, it is not found by the search used to fill the barcodeCache: https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/models/stock_quant.py#L104-L106 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/models/barcode_model.js#L37-L39 However, if the uom is not present in the barcode cache the `BarcodeQautnModel` will fail to createLinesState whihc raises a missing error: https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/models/barcode_quant_model.js#L712 https://github.com/odoo/enterprise/blob/26546bcd3beebc7f65ce08385441b6284b46598e/stock_barcode/static/src/lazy_barcode_cache.js#L107-L110 opw-6250090 Forward-Port-Of: odoo/enterprise#119754 Forward-Port-Of: odoo/enterprise#118813
A technical issue prevented users with specific access rights from viewing leave information in the Attendances Gantt View. This update corrects a rare access error that occurred when calculating leave intervals, ensuring all users can accurately see approved leave on the Gantt chart. The fix adds a temporary access layer to ensure correct calculations.
Original PR description
Version: - 19.0 Steps to reproduce: - Install Attendances and Time Off - Create an internal user. - Give the user: Attendances Officer access & No Time Off Officer/Manager rights - Create an employee…
Version: - 19.0 Steps to reproduce: - Install Attendances and Time Off - Create an internal user. - Give the user: Attendances Officer access & No Time Off Officer/Manager rights - Create an employee linked to the user. - Configure the employee with a Flexible Working Schedule. - Create and approve a Time Off request for the employee. - Open: Attendances -> Gantt View - Navigate to the month containing the employee's approved leave. Issue: - An access error is raised when opening a month that contains the employee's approved leave. Cause: - In `_handle_flexible_leave_interval`, the code accesses `leave.holiday_id` to read fields such as `request_unit_half`, `request_unit_hours`, and `request_hour_from/to` on the `hr.leave` model. - When the current user has Attendances Officer rights but no Time Off access(rare cases), the ORM access check on `hr.leave` raises an AccessError, even though this read is purely for internal calendar computation and does not expose leave data to the user interface. Fix: - Added sudo() on holiday_id to access the employee's leave details and compute the work interval as expected. Task-6264510 Forward-Port-Of: odoo/enterprise#119116
This update corrects a bug where inactive or archived taxes were incorrectly displayed in the bank reconciliation process. The fix ensures that users only see active taxes when reconciling bank statements, improving data accuracy and preventing potential errors in financial reporting. This resolves issue OPW-6245641.
Original PR description
### Issue:
When editing a line within the bank reconciliation widget, inactive and archived taxes are incorrectly available for selection
### Cause:
The bank reconciliation edit line form view carried the `{'active_test': False}` context on the `tax_ids` field
This context allowed archived taxes to be loaded and selected during creation and manual edition
### Fix:
Explicitly force `active_test: True` in the view context for the tax field to ensure only active taxes can be searched and selected by the user
### Steps to reproduce:
- Install `account_accountant`
- Create a new tax and set it to inactive
- Go to the Bank Reconciliation widget
- Create a bank statement line
- Set the account to 600000 Expenses
- Edit the line by clicking on the pencil icon
- Open the Taxes selection dropdown
Before the fix, the inactive tax is visible and available for selection by default
opw-6245641
Forward-Port-Of: odoo/enterprise#119522This update simplifies the messages displayed when a new task is created in Odoo, consolidating two lines into a single, clearer message. This change was made to improve the user experience and avoid confusion, specifically targeting new Odoo 19.1 installations. The fix addresses a technical issue related to message formatting.
Original PR description
Before this commit, when a new task was created in `project.task`, its creation message spanned two lines: "task created" and "task created for project XYZ". This commit unifies them into one to avoid confusion. The first line was caused by the message template having a description attribute. Even though editing the description will not fix the issue for existing databases, we chose to target the earliest possible version that a new customer might start from. The problem does not exist in 19.0. task-5999819
The Budget Report was previously unusable on large customer databases due to a performance bottleneck. This update optimizes the report's SQL query, significantly reducing loading times – now averaging 1.63 seconds for reports with up to 14 lines of data. This improves usability for users working with extensive financial data.
Original PR description
**Description** Opening the Budget Report from any budget record times out on databases with significant data volume. The request to `budget.report/formatted_read_grouping_sets` consistently times…
**Description**
Opening the Budget Report from any budget record times out on databases
with significant data volume. The request to
`budget.report/formatted_read_grouping_sets` consistently times out,
making the Budget Report completely unusable.
**Root cause:**
`budget.report` is an SQL view that consists of 5 UNION ALL branches.
When the list view loads, the ORM translates the `budget_analytic_id`
domain into a WHERE clause on the outer query wrapping the full UNION
ALL subquery. PostgreSQL cannot push this filter through a UNION ALL as
it's a hard optimization barrier. It must fully materialize the subquery
regardless of which budget is being viewed.
**Fix:**
Override _search on budget.report to extract budget_analytic_id and
budget_line_id conditions from the incoming domain using the Domain API.
budget_line_id is rewritten as Domain('id', op, value) so _to_sql()
correctly emits bl.id in the raw SQL. The resulting domain is injected
in context under budget_line_domain and read in _get_bl_query,
_get_aal_query (base module), and _get_pol_query (purchase module) to
filter budget_line rows inside each branch's LEFT JOIN ON clause.
This also removes the budget_report_budget_line_ids context key from
budget_line._compute_all, unifying both filters under one mechanism.
---
On customer DB (568k `account_analytic_line`, 27k `budget_line`,
116k confirmed `purchase_order_line`, 114k posted vendor bill lines
with purchase link):
| Budget | Before | After |
|---|---|---|
| 8 lines, 730d span | timeout | 2.27s |
| 14 lines | timeout | 2.39s |
| 14 lines, 1095d span | timeout | 1.63s |
- Before: https://explain.dalibo.com/plan/ehed5eb8de251426
- After: https://explain.dalibo.com/plan/db8aef35cag9hg6f
opw-6098047
Forward-Port-Of: odoo/enterprise#114692This update improves the accuracy of the reconciliation process by ensuring the matching dialog displays both draft and posted journal items. Previously, the dialog was limited by a default filter, leading to a reduced number of matching results. This change provides a more complete view for users to reconcile transactions.
Original PR description
The reconcile badge counts draft and posted journal items, but the matching dialog forces a posted filter by default, this makes the dialog show fewer lines than count as it discards the draft ones. Remove the default posted search filter so the dialog displays all matching items. task-6234801 Forward-Port-Of: odoo/enterprise#118146
This update fixes a visual issue on mobile devices where an unwanted caret appeared next to the 'Expand' button in the Inbox. It also corrected the alignment of header buttons, preventing them from wrapping onto multiple lines when the messaging menu was open. This ensures a cleaner and more professional user experience on mobile.
Original PR description
On mobile, an unwanted caret was displayed next to the message 'Expand' button in the Inbox because the messaging menu itself opens a dropdown, causing any nested Dropdown to automatically display a caret. This commit also fixes the alignment of the Inbox header action buttons, which wrapped onto multiple lines when opening the messaging menu on mobile while the Inbox tab was already selected. In this case, the `AutoresizeInput` width was computed at its maximum size, leaving insufficient space for the header action buttons and causing them to wrap onto multiple lines. Task-[6244177](https://www.odoo.com/odoo/project/1519/tasks/6244177) Forward-Port-Of: odoo/odoo#266343
This update fixes a bug where follow invitations weren't appearing in user inboxes unless a comment was added. The change ensures that the notification subject is always displayed, regardless of the comment content, ensuring users receive timely follow invitation notifications. This improves the user experience and prevents missed invitations.
Original PR description
Steps to reproduce: - Configure user A to receive inbox notifications. - As user B, invite user A to follow a record with Notify recipients enabled. - Open the inbox of user A. The Invitation to follow notification is not displayed in the inbox when no additional comment is provided. This happens because the notification body is empty unless extra comments are added. This commit fixes the issue by displaying only the subject when the body is empty. Task-[5485727](https://www.odoo.com/odoo/project/1519/tasks/5485727) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269511 Forward-Port-Of: odoo/odoo#244653
This update adjusts the format of unit prices in Polish VAT invoices (l10n_pl_edi) to ensure accurate calculations with the KSEF system. While the existing system technically works, this change aligns the unit price and total without tax, improving invoice accuracy and compliance. This resolves a minor discrepancy impacting invoice presentation.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice with a unit price of 10.005 and qty of 2. 2. Send the invoice to ksef. 3. Open the xml and notice P_9A (unit price) is 10.00 and P_11 (total without tax) is 20.01 Which is inconsistent (10.00 * 2 =/= 20.01). This PR increase the decimal places of P_9A to 8 digits which is the maximum allowed by the FA(3) format. Note that Ksef doesn't verify the untaxed unit price * quantity = total without tax, so the invoice we send are technically valid. However, it's best to generate invoice where the numbers add-up. opw-6203896 Forward-Port-Of: odoo/odoo#263812
This update optimizes the process of validating purchase orders by preventing unnecessary calculations of location weights. By reordering checks, the system avoids computing weights when other conditions already rule out a location, significantly speeding up validation times, especially with large numbers of locations. This improves overall system performance and responsiveness.
Original PR description
When checking if a stock.move.line can use a location as destination with the method `_check_can_be_used()`, we start by checking if the incoming products can be stored without exceeding the maximal…
When checking if a stock.move.line can use a location as destination with the method `_check_can_be_used()`, we start by checking if the incoming products can be stored without exceeding the maximal weight of the location. This needs to call the `_get_weight()` method to compute the forecasted weight for the location. This method relies on heavy computations and can become a bottleneck when we need to loop over a high number of locations. In some cases, we can rule out the location based on less expensive conditions that are verified after the weight one. We propose to invert the conditions check order to avoid computing the location weight when other conditions are not met. Steps to reproduce --------------- - Install stock and purchase modules; - Enable storage locations and categories in the settings; - Create a storage category: allow_new_product = same, max_weight=10.0 kg; - Create N locations using this category, parent_id=WH/stock; - Create a putaway rule to each location from WH/stock, for the new storage category and using a product A with a weight of 2 kg; - Create a stock.quant per location to store a product B, weight=2kg; - Create a purchase order with X lines for 1 unit of product A; - Validate the purchase order. The validation should take several seconds to execute as every locations will be rejected due to the storage category, but it will call _get_weight() first. Benchmark --------------- This improvement is very data specific and will be most useful when a lot of locations are using a storage category of type "empty" or "same". In addition, it also relies on the order in which we are treating the locations, if the acceptable locations are the first to be received in the method, it won't need to loop over all of them. The following benchmark was established in a production database in which every 6068 locations are using a category of type "same". | No stock.move.lines | Before PR | After PR | |---------------------|-----------|----------| | 40 | 168 s | 7.3 s | | 72 | 264 s | 12.33 s | When the only condition that can reject locations is the exceeding weight, this modification will slow down the process. However, the time loss in this case is smaller than the gain in the first case. The following benchmark was obtained by validating a purchase 1 line order with only fully filled locations. | No locations | Before PR | After PR | |--------------|-----------|----------| | 500 | 2.02s | 2.37 s | | 2000 | 7.85s | 9.76 s | | 10000 | 39.16 s | 48.86 s | opw-5949370 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270125 Forward-Port-Of: odoo/odoo#266872
This update resolves a bug where composite actions within website options could fail when using a 'getValue' function. The fix adds a test to ensure the action is properly bound, preventing errors and improving website functionality. This ensures consistent behavior across Odoo versions.
Original PR description
In 18.4 the composite action isn't used extensively, so the problem was unnoticed. However, if you use it with an action that has a `getValue` set, you may get issues, since the action will not be bound. Possible way to reproduce the issue: - Create an option that uses the `composite` action - Set `customizeWebsiteVariable` as a first action in the `actionParam` - Click on an element that has that option => You'll get an error. Note, that testing just this would be useless, so I added a test that tests that the action uses the first `getValue`. Without this fix the test would crash since in `getValue` `this` is unbound. Forward-Port-Of: odoo/odoo#269873
This update ensures that financial data associated with IoT boxes used in point-of-sale systems is properly handled before those boxes are removed from the system. This prevents potential data loss and maintains the integrity of sales transactions. It's a critical fix to avoid disruptions to our retail partners.
Original PR description
Before unlinking an iot.box from the database, we must ensure that its fiscal data module is not currently used in any pos.config. task-id: 5144489 Forward-Port-Of: odoo/enterprise#110099
This update fixes an issue where stock replenishment wasn't working correctly with orderpoints, leading to duplicate purchase orders being created. Now, the system intelligently updates existing purchase order lines when replenishing stock through orderpoints, specifically when the replenishment is triggered automatically. This ensures more efficient and accurate stock management.
Original PR description
Replenishing the stock from an orderpoint will look for a purchase order line having the same orderpoint_id in order to update the quantity instead of creating a new one. The issue is manual orderpoint are deleted right after the replenishment. Replenishing two times the same product will always create a new purchase order line. This commit makes the orderpoint_id is pass in the procurement values only in case of `trigger == auto` orderpoint. 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#269725
This update addresses a technical issue that could cause a software error when comparing history differences. The fix ensures the system gracefully handles empty history data, preventing a potential crash. This improves the stability and reliability of the web editor feature.
Original PR description
If, for whatever reason, the history we try to compare is an empty string, we might get a value error thrown. We guard the code to avoid the error. see :https://github.com/odoo/odoo/issues/269149 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269722
This update resolves an error that occurred when creating payment reports for Swiss companies. The issue stemmed from a missing module, which caused a system error when attempting to generate the report. This fix ensures that the payment report generation process works correctly regardless of whether the specific Swiss payroll module is installed.
Original PR description
*=l10n_ch_hr_payroll,hr_payroll_account_iso20022 When clicking the create payment report button on a payslip for a Swiss company, a traceback occurs if the ``hr_payroll_account_iso20022`` module is…
*=l10n_ch_hr_payroll,hr_payroll_account_iso20022 When clicking the create payment report button on a payslip for a Swiss company, a traceback occurs if the ``hr_payroll_account_iso20022`` module is not installed. Steps to reproduce the error: - Install ``l10n_ch_hr_payroll`` module - Switch to CH Company - Create an Employee and running contract for it - Go to Payroll > Payslip > All payslips > Create a new payslip > Set the employee > Confirm > Create payment report Traceback: ```py ValueError: Wrong value for hr.payroll.payment.report.wizard.export_format: 'iso20022_ch' ``` https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_ch_hr_payroll/models/hr_payslip.py#L383 https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_ch_hr_payroll/models/hr_payslip_run.py#L13 Here, ``iso20022_ch`` is passed as ``export_format``, However, ``iso20022_ch`` is added to the selection field in the ``hr_payroll_account_iso20022`` module at [1]. When that module is not installed, the selection value does not exist, leading to the above error. [1]: https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/hr_payroll_account_iso20022/wizard/hr_payroll_payment_report_wizard.py#L11 sentry-7391832811 Forward-Port-Of: odoo/enterprise#120295 Forward-Port-Of: odoo/enterprise#113277
This update fixes an issue where long text labels in SelectMenu multi-select tags were not being truncated, leading to a cluttered and less readable user experience. Now, tags are automatically shortened to fit, aligning with the design of Many2ManyTags and improving visual clarity.
Original PR description
Before: Tags in SelectMenu (multi-select) had no text-overflow handling. After: Tags now truncate text, consistent with Many2ManyTags behavior. task-5226503
This update fixes a minor visual issue in the web_studio module, where property tags within the SelectMenu were constrained to a limited width. Now, tags automatically expand to fill the available screen space, creating a cleaner and more user-friendly experience. This ensures a consistent and optimized layout for all property selections.
Original PR description
Before: Each tag was limited to 200px, leaving available space unused. After: Each tag now expands to 100% of the available width. task-5226503
This update resolves an issue where product searches weren't working correctly when using the autocomplete feature. The fix adjusts how product names are matched during searches, ensuring accurate results regardless of the search method (copy/paste or direct input). This improves the user experience when finding products.
Original PR description
Steps: - Create a product with a barcode "12345" - Create a sale order - Add a product - search product with name "12345" without copy/pasting - no result - try with copy/pasting - 1 result The problem is due to the fact that there is an optimization in Many2XAutocomplete.search which means that if no results are found for “1234,” it will not search for “12345.” However, product override name_search to returns a product only when the name is exactly equal to its barcode (`=` and not `ilike`), which does not work at all with search optimization. Since: https://github.com/odoo/odoo/pull/228035 opw-5908011 Forward-Port-Of: odoo/odoo#247978
This update resolves an issue where users were unable to edit the names of multiple projects simultaneously. The fix prevents a technical error that occurred when updating the names of multiple projects at once, ensuring a smoother user experience for managing project names.
Original PR description
Currently, an error will occur when user multi edits name of projects. Steps to replicate: - Install `project` and open projects. - From the list view select multiple projects and edit their name.…
Currently, an error will occur when user multi edits name of projects.
Steps to replicate:
- Install `project` and open projects.
- From the list view select multiple projects and edit their name.
Error:
```
File '/home/odoo/src/odoo/saas-19.3/addons/project/models/project_project.py', line 754, in write
analytic_account_to_update.write({'name': self.name})
File '/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py', line 1728, in __get__
record.ensure_one()
File '/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py', line 5341, in ensure_one
raise ValueError('Expected singleton: %s' % self)
ValueError: Expected singleton: project.project(8, 9, 10)
```
Cause:
- As multiple records were changed at the moment, `self` had multiple recordsets and trying to access `self.name` [1] causes this error.
Solution:
- Avoided accessing `self.name` on a multi-recordset during multi-edit.
- Updated analytic account names using the name recieved in the vals.
[1]: https://github.com/odoo/odoo/blob/a69ec43f490735f639292d116b0207182c5b2581/addons/project/models/project_project.py#L608
sentry-7452096418
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#269830
Forward-Port-Of: odoo/odoo#267620This update ensures that when users rename multiple projects simultaneously, the linked folder names are automatically updated. Previously, the system didn't reflect these changes, leading to inconsistencies. This fix improves data accuracy and simplifies project management.
Original PR description
Currently, when user multi-edits projects names from list view the linked folder name doesnt get updated. Steps to replicate: - Install `documents_project` and open projects. - Select multiple projects and edit their names. Issue: - The project names get updated but their respective linked folder's name doesnt get updated. Cause: - During multi-edit, `self.documents_folder_id` contains the folders of all selected projects. - As a result, `len(self.documents_folder_id.project_ids) == 1` [1] is evaluated on the combined recordset instead of per project, causing the condition to fail whenever multiple projects are renamed. Solution: - Avoided accessing `self.name` on a `multi-recordset` during multi-edit. - Filtered projects individually and updated their document folders using the name in vals. [1]: https://github.com/odoo/enterprise/blob/3c2985ca6011700c271ed14e40e08c89be822753/documents_project/models/project_project.py#L101 sentry-7452096418
This update prevents a crash during the installation of the Saudi Arabia E-invoicing module (l10n_sa_edi) in Odoo 19.1 and above. The issue occurred when required taxes were missing, and a code change disrupted the previous workaround. The fix ensures a smoother installation process.
Original PR description
Issue: Installing the `l10_sa_edi` E-invoicing module causes an error in versions 19.1 and above if any of the taxes in the `account.tax-sa.csv` are missing. This behavior was previously avoided via the post init function `_l10n_sa_edi_post_init()`, which no longer works due to the change made to ir_module.py fetching the template data during the module installation. Reproduction Steps: - Install Accounting - Configuration > Settings > Change "Fiscal Localization" to Saudi Arabia - Configuration > Taxes > Delete 0% "Not Subject to VAT" tax - Try to install `l10n_sa_edi` Saudi Arabia - E-invoicing Fix: Updated '_get_sa_edi_account_tax()` to filter out taxes that don't already exist on the database. Removed the `_l10n_sa_edi_post_init()` function since it should now be obsolete. Related ticket: opw-6293740
This update fixes a visual issue where portal cards on the customer portal lacked a background color. The issue was caused by a default color setting being incorrectly initialized. Now, all portal cards will have a consistent background color, improving the overall user experience and visual appeal.
Original PR description
Steps to reproduce: 1. Go to the "/my" or "/my/home" page. Issues: Portal cards do not have a background color by default. Cause: The `portal-card` color variable was initialized with a `null` value, preventing any default background color from being applied to portal cards. task-6250258
This update fixes a security vulnerability where users without approval rights could incorrectly interact with approval requests, leading to errors. The change restricts access to 'Accept' and 'Refuse' options within approval activities to only the designated approvers, ensuring proper workflow control.
Original PR description
Currently when a user submits an approval request, an activity is created for the approver who can validate or refuse the request directly from the activity, however these options are also visible to other users who will trigger an error if interacting with the options. This commit removes these options for users who are not the approver. **Steps to reproduce:** - Log in as admin - Go to approvals - Select dropdown menu of General Approval and Edit - Change documents to optionnal - Make sure admin is in the approvers list - Log in as demo - Go to approvals -> General Approval -> New Request - Submit the request - You'll see an activity be created for admin, with Accept and Refuse options - If you select any of these options you will get an access error opw-5423528 Forward-Port-Of: odoo/enterprise#109047
This update corrects a validation error that previously prevented the import of Polish VAT invoices (KSeF) when certain required fields (`P_9A` and `P_11`) were missing or had zero values. The fix allows invoices with these fields absent to be processed correctly, ensuring accurate VAT reporting and avoiding disruptions to the invoice import workflow.
Original PR description
When importing bills, if `P_9A` and `P_11` are absent or zero, a `UserError` is raised: `No net or gross unit price found in the FA (3) for the line with the product.` **Steps to reproduce:** - Upload the problematic XML file as an attachment via `Settings -> Technical -> Attachments` - Create a `validator` server action with the code provided in the referenced ticket, with the `Add Contextual Action` flag set - Reload the page - Select the attachment in list view - Click the gear icon - Run the newly created server action KSeF FA(3) schema documentation: https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf Ticket [link](https://www.odoo.com/odoo/project.task/6211065) opw-6211065 Forward-Port-Of: odoo/odoo#265228
This update optimizes the MRP work order process by preventing unnecessary BoM explosions for quality points like instructions and pass/fail checks. Previously, this process was slow, but now it's significantly faster, improving work order processing times. This change focuses on efficiency and reduces the load on the system.
Original PR description
`_compute_component_ids` unconditionally called `bom.explode()` for every product variant on the BoM, even for quality point types (`instructions`, `pass_fail`, etc.) that never use the `component_id` picker. The field is only meaningful for `register_consumed_materials` and `register_byproducts`. Restrict the expensive path to those two types with an `elif` so all other types return `component_ids = False` immediately. | # Input data | Before PR | After PR | |:---:|:---:|:---:| | 10 variants, 10 components, 2 phantom BoMs, 3 ops | 841 ms | 0.1 ms | | 30 variants, 20 components, 5 phantom BoMs, 3 ops | 1,343 ms | 0.1 ms | | 80 variants, 40 components, 12 phantom BoMs, 5 ops | 8,674 ms | 0.1 ms | OPW-6210368 Forward-Port-Of: odoo/enterprise#118470
This update fixes an issue where the pricing calculation for products sold in large quantities (like boxes of screws) was inaccurate. By allowing higher precision for the ‘Base Unit Count,’ the system now correctly calculates reference prices for these products, ensuring accurate sales pricing. This improves the overall reliability of product pricing in the website sale module.
Original PR description
**Description of the issue/feature this PR addresses:** The `Product Reference Price` feature in `website_sale` cannot correctly handle products sold in large packs when the reference quantity…
**Description of the issue/feature this PR addresses:** The `Product Reference Price` feature in `website_sale` cannot correctly handle products sold in large packs when the reference quantity requires a very small `base_unit_count`. For example, a product sold as a `box of 10000` screws should be able to use `0.0001` as its `Base Unit Count`, so the reference price can be computed against the box quantity correctly. **Current behavior before PR:** `base_unit_count` uses the default float precision, so values with more than two decimal places are rounded in the product form. When trying to set `Base Unit Count` to `0.0001`, the value is rounded to `0.00` / `0.01`, which makes the Product Reference Price computation incorrect. Steps to reproduce: 1. Go to Settings > Website and enable Product Reference Price. 2. Create or open a product named `Screws`. 3. Set Sales Price to `$ 1.00`. 4. On the product form, set Base Unit Count to `0.0001`. 5. In Custom Unit of Measure, type `box of 10000` and press Create. <img width="1374" height="740" alt="1" src="https://github.com/user-attachments/assets/2d4f7863-b2cd-4c7c-87e1-11526dc50551" /> **Desired behavior after PR is merged:** `base_unit_count` keeps high-precision values such as `0.0001`. This allows `Product Reference Price` to correctly support large-pack scenarios, such as selling screws in a `box of 10000`, by storing `base_unit_count` with unlimited numeric precision. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262579
This update corrects a problem where Google Calendar attendee information wasn't syncing correctly when an attendee's email matched a configured alias. The fix ensures that all Google attendees are properly synchronized, preventing data loss and improving the reliability of calendar events. This resolves an internal issue (opw-6086240) impacting event attendance accuracy.
Original PR description
_get_sync_partner excludes partners whose email matches a configured alias, returning a list shorter than the emails/google_attendees lists. zip() stops at the shortest, silently dropping the last Google attendee instead of the alias-matched one. Fix by replacing the positional zip with a by-email dict lookup, so each attendee is resolved independently and only the unresolvable one is skipped. opw-6086240 Forward-Port-Of: odoo/odoo#263787
This update resolves a bug that occurred when propagating delivery carriers from sale orders to purchase order receipts. Specifically, a shared receipt was causing a conflict when different carriers were assigned to sale orders. This fix ensures that carrier assignments are handled correctly, preventing errors and improving the reliability of purchase order creation.
Original PR description
Steps to reproduce 1. Set warehouse to 2-step incoming (Input → Stock) 2. Enable "Propagation of carrier" on the push rule (Input → Stock) 3. On the vendor, set "Purchase Orders Grouping" to "Always"…
Steps to reproduce 1. Set warehouse to 2-step incoming (Input → Stock) 2. Enable "Propagation of carrier" on the push rule (Input → Stock) 3. On the vendor, set "Purchase Orders Grouping" to "Always" 4. Create a storable product with the Buy route and that vendor 5. Create two sale orders for that product, each with a different delivery carrier 6. Confirm both sale orders → a single merged purchase order is created 7. Confirm the purchase order → a receipt (Vendors → Input) is created 8. Validate the receipt → ValueError: Expected singleton: delivery.carrier(1, 3) Issue In `_get_new_picking_values`, when the push rule fires to create the internal transfer (Input → Stock), the carrier is fetched from the referenced sale orders: carrier_id = self.reference_ids.sale_ids.carrier_id.id https://github.com/odoo/odoo/blob/5fb0c1f1460949043aa23ddbed09bdbfdc4a8482/addons/stock_delivery/models/stock_move.py#L45 Because both sale orders share the same merged receipt, the receipt move references both. When those SOs have different carriers, `self.reference_ids.sale_ids.carrier_id` returns a multi-record recordset and calling `.id` raises `ValueError: Expected singleton: delivery.carrier(1, 3)`. opw-6126760 Forward-Port-Of: odoo/odoo#262671
This update resolves an issue where changing a company's country caused errors in Time Off functionality due to linked leaves and allocations. The change restricts company country updates unless there are no related Time Off records, ensuring smoother operation after a country modification. This improves data consistency and prevents disruptions to Time Off processes.
Original PR description
When a Time Off Type is created, it inherits the country of the current company. If there are leaves or allocations created from this Time Off Type and the company's country is then changed, various…
When a Time Off Type is created, it inherits the country of the current company. If there are leaves or allocations created from this Time Off Type and the company's country is then changed, various parts of Time Off will throw access errors as the leaves and allocations are still tied to the former country. The goal of this PR is to constrain the company country from being changed unless there are no such leaves or allocations. **Steps to Reproduce on Runbot:** 1. Ensure the current company has a `country` set, e.g. "My Company (San Fransisco)" has country set to "United States". 2. Access Time Off as Mitchell Admin. 3. Create a new Time Off Type, for simplicity's sake without a need for allocation or approval, ex: "Gone Fishing". Note this Time Off Type will have the `country` set to the company country by default. 4. Take "Gone Fishing" time off. 5. Change or set blank the company's `country` value. 6. Ensure the record rules cache is flushed. 7. Try to access Time Off. opw-6206359, opw-6140496 closes #263950 Forward-Port-Of: odoo/odoo#263950
This update fixes an issue where overtime details weren't correctly displayed in attendance records. The visibility condition for overtime information was reversed, preventing accurate reporting. This change ensures that overtime hours are now correctly shown when creating attendance records, providing more reliable tracking of employee time.
Original PR description
Steps: * Create an extra-hours attendance for an employee that has overtime ruleset OR * Create an extra-hours attendance for an employee that has no overtime ruleset Issue: * The overtime details in the attendance view visibility condition was flipped Solution: * Reverse the visibility condition of the XML element Task: 6295710 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#269744
A confusing error message related to loyalty discount codes has been resolved. The fix clarifies the issue for users, ensuring they understand why a discount wasn't applied when a minimum purchase requirement wasn't met. This improves the user experience and reduces potential frustration.
Original PR description
Issue: Error message was ambiguous and left users wondering what was wrong. Steps to reproduce: Set a discount code where the conditional rule is set to "minimum purchase" among specified products. Then, spend an amount larger than this on unrelated products and try to apply the discount code. "A minimum of x(currency) should be purchased to get reward" Cause: Poor error message caused ambiguity Solution: Corrected the error message so that the user can better understand where the issue is. opw-6290514 Forward-Port-Of: odoo/odoo#269319
This update simplifies accessing employee profiles from the avatar card. Previously, a confirmation dialog forced users to activate inactive companies. Now, a 'View Profile' dropdown offers two options: directly opening the employee profile (activating the company) or accessing the contact profile without company activation. This provides a smoother user experience while addressing potential concerns about broad company scope.
Original PR description
When opening a profile from the avatar card, the employee's company may not be in the user's active companies. Until now this popped a confirmation dialog that only let the user either activate the…
When opening a profile from the avatar card, the employee's company may not be in the user's active companies. Until now this popped a confirmation dialog that only let the user either activate the other company or cancel, with no way to reach the still-accessible contact profile. Replace the dialog with a less intrusive "View Profile" dropdown, shown only when the employee's company is allowed but not active. It offers two choices: - Open Employee Profile (activates the company) - Open Contact Profile (no company activation) Activating an extra company widens the active-company scope for the whole session, which is not always desirable, so keeping a non-mutating path to the contact profile is useful. In every other case (no employee, company already active, or company not allowed) the plain "View Profile" button is unchanged. task-6074597 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264073
This update resolves a requirement from Luxembourg auditors regarding the classification of partners in our SAFT reports. Specifically, it ensures that less than 30% of transactions with payable or receivable accounts have missing supplier or customer IDs. The changes add partners to the relevant lists based on transaction types and maintain compatibility with older report formats.
Original PR description
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on…
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on \Transaction\Line elements is determined by a partner's `customer_rank` and `supplier_rank`. This is a binary designation, one or the other. The Luxembourg FAIA report requires that less than 30% of \Transaction\Line elements with payable accounts (class 6) can not have \SupplierID. The same applies for \Transaction\Line elements with receivable accounts (class 7) and the \CustomerID element. TSB clarified that any partner on an receivable or payable line should be added to the Customer list or Supplier list respectively https://github.com/odoo/enterprise/pull/100749#issuecomment-3655127511. In addition, I verified that Luxembourg's analysis of four separate FAIA files (from ticket 5427296) aligns with this expectation. <img width="1322" height="690" alt="image" src="https://github.com/user-attachments/assets/1a82f99e-5b32-4dbb-96e1-1b25bab2629b" /> This commit adds partners to the \Supplier and \Customer lists if they have any payable or receivable lines, respectively. It also picks between the \CustomerID and \SupplierID based on a line's `account_type`. This logic is applied to `account_saft` and updates the other, country-specific SAFT reports where appropriate. It also retains the previous `customer_rank` and `supplier_rank` logic as a fallback for older XML reports and for accounts other than `asset_receivable` or `liability_payable`. opw-6118024 Forward-Port-Of: odoo/enterprise#120131 Forward-Port-Of: odoo/enterprise#118714
This update resolves an issue where UBL import failed due to a mismatch between the product's and imported unit of measure categories. The fix allows imports to proceed without error, and users can manually adjust the UoM after the import is complete. This improves the reliability of UBL invoice processing.
Original PR description
The new collected_values UBL import flow sets product_uom_id from the XML unitCode without checking that the resolved UoM category matches the matched product's UoM category. When they diverge, writing the line triggers the incompatible error. Steps to reproduce: - Create a product "XYZ" with UoM "Units" (category "Unit"). - Import a Peppol UBL bill whose line has Item/Name "XYZ" and unitCode="MTK" (uom_square_meter, "Surface"). - Import fails with: "The Unit of Measure (UoM) 'm²' you have selected for product 'XYZ', is incompatible with its category : Unit." This fix will avoid setting the product_uom_id when the UoM category doesn't match the product's UoM category, allowing the line to be imported without error. The user can then manually set the correct UoM after import. opw-6121714 Forward-Port-Of: odoo/odoo#269933 Forward-Port-Of: odoo/odoo#269714
This update resolves a problem where invoice sending with the l10n_fr_pdp module failed due to incorrect retrieval of PEPPOL identifiers. The fix ensures that the correct commercial partner is used to obtain these identifiers, guaranteeing compliance with French PEPPOL requirements for invoices.
Original PR description
…cial partner **STEP TO REPRODUCE** 1. Install l10n_fr_pdp. 2. On the demo FR company contact, create a new contact of type invoice address. 3. Create an invoice with this new contact, and try send the invoice. 4. The pdp invoice constraints checking for pdp identifiers fails. **CAUSE** We use the partner to retrieve the peppol_eas and peppol_endpoint field values, but for subcontact, those field are empty. We should use the commercial_partner_id which correspond to the company we try to invoice instead. opw-6235830 Forward-Port-Of: odoo/odoo#270014
This update fixes a potential instability issue with the PDP registration process. By moving a key function to the company record, we ensure the registration process remains reliable even if the temporary PDP registration model is deleted. This improves the overall robustness of the system.
Original PR description
The aim of this commit is to move _get_iap_url on res.company model instead of pdp.regitration. This move is made for 2 reasons: 1. PDP registration is a transient model which means that the object could be deleted in the time. 2. PDP registration implementation was using the model (api.model) and the record (self.edi_mode) which is a bad implementation. So by moving this function on company, we ensure that we always have a record to call the function and then the function is no longer an api.model. no task id --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270345