Daily updates from Odoo
Thursday, June 4, 2026
41 changes · master
New functionality added to Odoo
This update integrates official worker ONSS statuses into the Odoo Enterprise Belgian localization. This collaboration with Partena ensures accurate payroll processing by aligning with Belgian labor regulations and improving data consistency.
Original PR description
As part of the payroll collaboration with Partena, official worker ONSS statuses needed to be added to the belgian localization. Task: 6174501
This update adds test data related to a new payment method, 'pos_iot_six,' to the Odoo configuration tests. This ensures that the system can properly handle and test this new payment option during development and quality assurance. It supports the ongoing development of the Odoo Enterprise platform.
Original PR description
Adding pos iot six payment method to the test data of the pos_config. Related to Odoo pr https://github.com/odoo/odoo/pull/262184 Forward-Port-Of: odoo/enterprise#118865 Forward-Port-Of: odoo/enterprise#118531
Enhancements to existing features
This update introduces a new feature that allows users to easily compare all report lines to a single, chosen line, displaying percentage differences. This enhances reporting accuracy and provides a clearer understanding of variances. The feature is designed to work optimally within a single column view, ensuring a reliable user experience.
Original PR description
This feature allows users to compare all report lines against a specific, user-selected line. An additional column is then displayed with a percentage. Note that this only works when in a single column group. When using more than one, the feature is disabled (and the filter is hidden, so that we don't promise a feature that's not working). task-5144252
This update resolves an issue preventing Odoo invoices from being accepted by the Colombian Tax Authority (DIAN). Previously, global discounts were handled incorrectly, requiring manual adjustments. Now, discounts are automatically applied to individual lines during XML generation, ensuring compliance and streamlining the invoicing process.
Original PR description
Current Behavior: The Colombian Tax Authority (DIAN) does not accept negative lines in the electronic invoice XML, but promotions, coupons, and global discounts are added as separate negative order lines. As a workaround, users have to manually apply discounts to each line which is inefficient. Change: To allow users to use "Coupons and Loyalty" features to apply global discounts, the negative lines will be redistributed into line-level discounts during the XML generation. Expected Behavior: Users will continue to see negative lines in Odoo, but the negative lines will be redistributed to the invoice lines as discounts, so the DIAN will accept the XML. task-5412446
This update ensures the knowledge tour continues to function correctly following recent changes to the media dialog system. It’s a necessary adjustment to maintain a smooth user experience for accessing and understanding knowledge articles. This change improves the overall usability of the knowledge base.
Original PR description
Modify knowledge tour to stay compatible with the media dialog refactoring task-5318096
This update enhances Odoo's performance by ensuring proper indexing on related data fields. Specifically, it optimizes how Odoo recalculates information based on dependencies, leading to faster updates and a smoother user experience. This change addresses a potential performance bottleneck within several key modules.
Original PR description
See https://github.com/odoo/odoo/pull/258675 task-6095328
This update improves the demo experience by allowing the 'Create Vendor Bill' action to function without requiring OCR processing. It replaces PDFs with Peppol XML equivalents, streamlining the demo setup and making it easier to showcase the feature. This change primarily impacts the documents account module.
Original PR description
Purpose ======= For demo purpose, it would be nice to be able to trigger the "Create Vendor Bill" action without needing OCR. So we replace some PDFs by their peppol XML equivalent in documents account, and we include the XML in the embedding of the PDFs defined in the documents module for some others. Simplify the demo prompt by removing the text in bold. Task-6236411
This update optimizes the generation of payroll reports in the Odoo Enterprise system. The previous process was slow, taking around 7 seconds. This change significantly reduces processing time, improving efficiency and user experience.
Original PR description
Investigation in process. task-6259077
This update enhances the employee avatar card by displaying key payroll information – wage, pay frequency, and employment category – directly within the popup. This provides users with a quick overview of an employee's payroll details. The changes are restricted to users with specific payroll access permissions.
Original PR description
Show wage (with currency and pay frequency), employment category, and seniority in the footer of the employee avatar card popup. The section is only sent to and rendered for users with `hr_payroll.group_hr_payroll_user` access. task-6117982
Resolved issues and error corrections
This update fixes a readability issue in appointment email templates when dark mode is enabled. The team adjusted background colors and simplified template code to ensure content is clearly visible for all users. This improves the overall user experience and consistency across Odoo.
Original PR description
This PR fixes and improves the display of the mail templates and also cleans their code. For this, several commits are needed: - Commit 1 sets the mails' background color to white because a dark custom color has been specified. Before this change, the content was not readable when the dark mode was enabled since the background and the font had similar colors. - Commit 2 adds default values to avoid displaying variables that users cannot understand inside the editor and replaces some t-attf-style by style, as they contain no variable. Community PR: https://github.com/odoo/odoo/pull/249102 Task-5886471
This update resolves an issue where users without sign permissions were unable to access records with sign request activities, resulting in an access error. The fix uses 'sudo' to ensure access and prevents actions that trigger the error, improving the sign request workflow for all users.
Original PR description
**Steps to reproduce** - Have user A with Sign admin rights and user B without Sign rights. - With user A, create a sign request activity on a record that user B can access. Send the signature…
**Steps to reproduce** - Have user A with Sign admin rights and user B without Sign rights. - With user A, create a sign request activity on a record that user B can access. Send the signature request. - With user B, try to access the record. -> AccessError when trying to fetch the chatter. **Cause** By default, users get access to all the activities associated to records they have access to (see `_search` of `mail.activity`). This is an issue since some of the fields added in `_store_activity_fields` for the sign request activity display might not be accessible for a user with access to the activity. **Change** Use `sudo` to be able to display the activity, even if the user doesn't have access to the sign request. Also, in that case, `can_write` should be `False` in order to hide the action buttons of the activity, which trigger access errors when trying to make operations on the sign request. Another related change is to create the activity for the user creating the sign request, this avoids falling back on the `user_id` of the record associated with the activity and makes sure the activity's user has access to the sign request. opw-6157455 Forward-Port-Of: odoo/enterprise#118555 Forward-Port-Of: odoo/enterprise#116540
This update adds a direct link within the Timesheets Assistant to its official documentation. This makes it easier for users to quickly find answers to their questions and understand how to use the Timesheets Assistant effectively. It’s a small change designed to improve user support and knowledge.
Original PR description
This commit adds documentation link in Timesheets Assistant to redirect the user to the documentation of Timesheets Assistant. task-6095833 Forward-Port-Of: odoo/enterprise#119022 Forward-Port-Of: odoo/enterprise#118754
This update resolves an issue where the system incorrectly flagged incoterm requirements for export invoices containing service products. Previously, the system demanded incoterm information even for services, which is not required by tax regulations. This change ensures accurate invoice export to the tax agency.
Original PR description
With l10n_gt_edi: - Create an invoice with a partner without a country (in l10n_gt this is considered an export invoice) and a service product. When trying to export the invoice to the tax agency, the following alert is triggered: Incoterm is required on export invoice with goods product but it's currently missing However, service products do not require incoterm configuration. opw-6170409 Forward-Port-Of: odoo/enterprise#115833
This update corrects a misunderstanding in the payment flow for orders with a price of zero. Previously, paying a sum through the 'customer account' method incorrectly treated it as a return. The fix now hides the 'pay_later' payment method when the order price is zero, aligning with business requirements and preventing incorrect accounting.
Original PR description
Step to reproduce: - install "pos_settle_due" - create a pos order, set order price = 0, select a customer - go to payment page, select "customer account" as payment method - here you can set any…
Step to reproduce: - install "pos_settle_due" - create a pos order, set order price = 0, select a customer - go to payment page, select "customer account" as payment method - here you can set any amount to pay, ex 100$ - fulfill the order. Observation: - the order amount is 0, if we pay 100$ using customer account, it is considered as change (which means we returned it to customer) - As per PO, this flow doesn't make sense Issue: - customer has 100$ due for this order, but he won't be able to settle this as fetch order to settle with amount != 0, after commit [1] - [1] https://github.com/odoo/enterprise/commit/12af23d5382e972facfaa999e4c5ab30c97e8d1f https://github.com/odoo/enterprise/blob/951e5f42884c898bc14d9c32ae6a8f08c31ff06d/pos_settle_due/static/src/app/screens/partner_list/partner_line/partner_line.js#L35 Fix: - we hide payment method of type "pay_later" in case of 0 price order opw-6123699 Forward-Port-Of: odoo/enterprise#118864 Forward-Port-Of: odoo/enterprise#116556
This update optimizes the styling of the Odoo Enterprise home menu by replacing inefficient CSS selectors with CSS variables. This change improves page loading speed and overall performance, leading to a smoother user experience. The update ensures the home menu remains responsive and fast.
Original PR description
Avoid selectors after `:hover` and `:active`, as they can impact performance. CSS variables are now used instead. Replace hex color values with "0 0 0" RGB syntax to ensure compatibility with CSS variable usage. Forward-Port-Of: odoo/enterprise#119082
This update fixes an issue where intercompany sales and purchases with multiple identical products resulted in incorrect stock reservation during receipt picking. The fix ensures that all units of a product are properly reserved when processing intercompany transactions, preventing discrepancies in inventory tracking. This improves the accuracy of stock management between companies.
Original PR description
…lit for same-product lines When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned: - Enable Inter-Company…
…lit for same-product lines
When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned:
- Enable Inter-Company Transactions on both companies (Create and validate)
- Create SO in company A to company B with 2 lines having the same product P, Confirm. => Delivery in company A, Purchase and Receipts in company will be created => The SO/PO/Delivery/Receipt will all have 2 lines
- Validate delivery => On the receipt, the 2 units of P are reserved on the 1st move, and the 2nd move is not reserved.
https://github.com/user-attachments/assets/b4816051-120e-4226-9228-fd552649d5ef
---
### Test result without fix:
```
2026-04-23 13:16:44,577 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: Starting TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product ...
2026-04-23 13:16:44,949 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: ======================================================================
2026-04-23 13:16:44,949 48027 ERROR oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: FAIL: TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product
Traceback (most recent call last):
File "/home/odoo/Odoo/src/18.0/enterprise/sale_purchase_stock_inter_company_rules/tests/test_inter_company_so_to_po.py", line 109, in test_02_inter_company_multiple_lines_with_same_product
self.assertRecordValues(purchase_from_a.picking_ids.move_ids, [
File "/home/odoo/Odoo/src/18.0/odoo/odoo/tests/common.py", line 709, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'pr[18 chars]0, 'quantity': 1.0}, {'product_uom_qty': 1.0, 'quantity': 1.0}] != [{'pr[18 chars]0, 'quantity': 2.0}, {'product_uom_qty': 1.0, 'quantity': 0.0}]
First differing element 0:
{'product_uom_qty': 1.0, 'quantity': 1.0}
{'product_uom_qty': 1.0, 'quantity': 2.0}
- [{'product_uom_qty': 1.0, 'quantity': 1.0},
? ^
+ [{'product_uom_qty': 1.0, 'quantity': 2.0},
? ^
- {'product_uom_qty': 1.0, 'quantity': 1.0}]
? ^
+ {'product_uom_qty': 1.0, 'quantity': 0.0}]
? ^
```
OPW-6145683
Forward-Port-Of: odoo/enterprise#118805
Forward-Port-Of: odoo/enterprise#114873This update fixes a problem where AI responses weren't being correctly delivered to embedded AI Livechat instances. The issue stemmed from how the system handled streaming data, and has been resolved by changing the way the AI response is delivered, ensuring proper functionality for embedded livechat experiences.
Original PR description
AI livechat embedded on another origin could not receive AI responses. The response stream is requested with fetch(), so it bypassed the livechat CORS routing that only wraps RPC calls. The matching CORS controller was also exposed as JSON-RPC, which cannot return the streamed HTTP response correctly. Expose the CORS endpoint as an HTTP stream, route the embedded fetch call to it, and pass the livechat guest token explicitly. task-id-6201054 Forward-Port-Of: odoo/enterprise#118916 Forward-Port-Of: odoo/enterprise#117535
This pull request resolves errors occurring when generating CFDI invoices for payslips including IMSS disability time off. The fix ensures the required 'Incapacidades' node is correctly declared in the XML, addressing a legal requirement for Mexican payroll reporting. It also corrects an incorrect calculation of the total amount due, ensuring accurate invoice generation.
Original PR description
Several error are logged in the chatter when signing a payslip that includes an IMSS disability time off. Steps to reproduce: * Install l10n_mx_hr_payroll_account modules * Switch to "INNOVACION…
Several error are logged in the chatter when signing a payslip that includes an IMSS disability time off.
Steps to reproduce:
* Install l10n_mx_hr_payroll_account modules
* Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company
* Go to Employees and open Cesar Osbaldo Cruz Solorzano
* Click on "Time Off" smart button and create a new time off with "Disability due to illness (IMSS)" type for "02/01/2026"(Any date).
* Go to Payroll > Payslips > Payslips and create a new pay run
* Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Monthly' and the Period '01/01/2026 -> 01/31/2026'
* Click on Continue, select Cesar and click on Select
* Open the payslip, click on "Validate" and "Ok"
* Mark as paid, open the "Journal Entry" from the smart button and click on "Post".
* Back to the payslip, and click on "Generate CFDI" button.
* An error is added to the chatter.
### Missing node to declare disabilities
Original message
```py
An error occurred while signing the CFDI document with the government:
Code : NOM111 Message : Error no clasificado. Extra Info : El nodo
"Incapacidades" se debera informar si se incluye en percepciones la
clave 014 "Subsidios por Incapacidad" o bien en deducciones la clave 006
"Descuento por incapacidad".
```
Translated message
```py
An error occurred while signing the CFDI document with the government:
Code: NOM111 Message: Unclassified error. Extra Info: The "Incapacidades"
(Disabilities) node must be reported if the perception key 014
"Subsidios por Incapacidad" (Disability Subsidies) is included, or if
the deduction key 006 "Descuento por incapacidad" (Disability Deduction)
is included.
```
Legal Context:
According to Mexican law, IMSS disabilities must be declared in a specific XML node.
There are two primary scenarios for reporting these amounts:
* Deduction (Type 006): The employer does not pay for these days, as the IMSS is responsible for the payment to the employee.
This is the most common scenario.
* Perception (Type 014): The employer pays for these days as a superior benefit. For example, by law, the IMSS does not pay for the first 3 days of a disability due to illness, and employers are not obligated to cover them either. However, companies offering superior benefits may choose to pay these days as a "Disability Subsidy."
Solution:
The chosen approach is to configure the Deduction node.
For the `l10n_mx_regular_pay_imss_disabilities` rule, the `l10n_mx_concept` has been set to `l10n_mx_concept_d6` (D06 - Disability Deduction). This ensures the required node is added.
### Missing "ImporteMonetario" attribute
Original message
```
An error occurred while signing the CFDI document with the government:
Code : NOM95 Message : El atributo Deduccion:Importe no es igual a la
suma de los nodos Incapacidad:ImporteMonetario, ya que la clave
expresada en Nomina.Deducciones.Deduccion.TipoDeduccion es "006".
```
Translated message
```
An error occurred while signing the CFDI document with the government:
Code: NOM95 Message: The attribute "Deduccion:Importe" does not match
the sum of the "Incapacidad:ImporteMonetario" nodes, as the key
expressed in "Nomina.Deducciones.Deduccion.TipoDeduccion" is "006".
```
Problem:
The "Incapacidades" node requires the "ImporteMonetario" attribute, which should represent the sum of the monetary value associated with the disabilities.
Solution:
Add the "ImporteMonetario" attribute and calculate its value using `l10n_mx_daily_salary`.
### Invalid "DiasIncapacidad" format
```py
An error occurred while signing the CFDI document with the government:
Code : 301 Message : XML mal formado Extra Info : Element
'{[http://www.sat.gob.mx/nomina12}Incapacidad](http://www.sat.gob.mx/nomina12%7DIncapacidad)', attribute
'DiasIncapacidad': '4.0' is not a valid value of the local atomic type.
```
Problem:
Altough the defaultdict where the values are sum up, `number_of_days` is
a float field, and when we get back the value, it is a float, adding for
example 4.0 instead of 4, which is not a valid value.
Solution:
Cast the value to int.
### Duplicate deduction on disabilities
```py
Wrong python code defined for:
- Employee: Cesar Osbaldo Cruz Solorzano
- Version: False
- Payslip: Salary Slip - Cesar Osbaldo Cruz Solorzano - 05/01/2026 - 05/15/2026
- Salary rule: ISR (Income Tax) (ISR)
- Error: TypeError('cannot unpack non-iterable NoneType object') while
evaluating
"
def find_rates(x, rates):
for low, high, fix, rate in rates:
if low <= x <= high:
return low, high, fix, rate
gross = categories['GROSS']
result = 0
if gross:
isr_table = payslip._rule_parameter('l10n_mx_isr_tables')[version.schedule_pay]
low, high, fix, rate = find_rates(gross, isr_table)
result = -((gross - low) * rate + fix)
period_factor = payslip._rule_parameter('l10n_mx_schedule_table')[version.schedule_pay]
if period_factor >= 15:
period_factor = (period_factor / 30) * (365 / 12)
min_wage = payslip._rule_parameter('l10n_mx_daily_min_wage') * period_factor
if gross <= min_wage:
result_qty = 0.0
"
```
Problem:
The IMSS disability amount is being deducted twice:
1. During "Worked Days" calculation, the IMSS disability is already not considered because the work entries belong to the "Unpaid Work Entry Types" of "Mexico: Regular Pay" structure.
2. During "Salary Computation", the `IMSS_DISABLE` salary rule deducts another time because it is in the `TAXABLE_ALW` category, and this one is deducted in the `NET` rule.
When the disability covers more than half of the period (e.g., 20 days in a monthly schedule), the double deduction causes the NET to become negative. This prevents the ISR rule from finding a correct stage in the tax tables, leading to a traceback.
Example: For a monthly wage of 30,000.0 and 5 disability days:
- The total amount in "Worked Days" is 25,000.0 (disabilities already deducted).
- The IMSS_DISABLE rule calculates -5,000.0, and when the NET rule is calculated, the disabilities are deducted again. Total NET becomes 16,843.84 instead of the expected 20,834.85.
Solution:
Change the rule category to `INTERMEDIARY_COMPUTATION` and avoid the double deduction when the `NET` is calculated, as it is already considered in the "Worked Days".
### Incorrect values in the XML
The signing process completes without errors, but some amounts in the generated XML are incorrect.
Problem:
The introduction of the Deduction 006 (Disability) directly impacts the calculation of the SubTotal and Total attributes in the Comprobante node.
For a monthly payslip with a wage of 30,000.00 (daily salary of 1,000.00) and 5 disability days (work risk), the values are calculated incorrectly as follows:
Attribute | Calculation | Actual Value | Correct Value
---------------------|----------------------------------|--------------|--------------
Comprobante:SubTotal | Sum of Perceptions (P01) | 25000.00 | 30000.00 (1)
Comprobante:Total | SubTotal - Total Deductions (2) | 15803.74 | 20803.74
(1) Must include the 5,000.00 from disabilities to balance the deduction.
(2) Total Deductions = D06 (5,000.00) + ISR (3,451.65) + IMSS (744.61) = 9,196.26.
The Total is currently undercalculated because the 5,000.00 is being
deducted from the SubTotal that already had those 5,000.00 excluded.
Solution:
Since the `SubTotal` is derived from Perceptions, and the "(P01)
Salaries, Wages, Stripes, and Day Labor" amount is driven by the
`GROSS_WITHOUT_HOLIDAY` rule, the disability amount must be added. This
balances the Deduction 006, ensuring `SubTotal` is correct.
### Absenteeism and Disabilities
By law, the calculation of IMSS contributions depends on these two types of unpaid days:
* Disabilities: Refers to medical leave issued by the Institute (IMSS).
* Absenteeism: Refers to unjustified leave; apply for periods of fewer than 8 days.
Source: [Artículo 31](https://www.imss.gob.mx/sites/all/statics/pdf/leyes/LSS.pdf)
Translated text:
Article 31. When wages are not paid due to the employee's absence from work, but the employment relationship persists, the monthly contribution shall be adjusted according to the following rules:
I. If the employee's absences are for periods of fewer than eight consecutive or non-consecutive days, contributions shall be calculated and paid for such periods only for the sickness and maternity insurance...
If the employee's absences are for periods of eight consecutive days or more, the employer shall be released from the payment of employer-employee contributions...
IV. In the case of absences covered by medical disabilities issued by the Institute, it shall not be mandatory to cover the employer-employee contributions, except regarding the retirement branch.
The following table summarizes the contribution requirements based on the type of absence:
Insurance Branch (RAMA) | Section I (Absenteeism) | Section IV (Disability)
--------------------------------|-------------------------|------------------------
Sickness and Maternity | Paid | Not Paid
Disability and Life | Not Paid | Not Paid
Severance and Old Age | Not Paid | Not Paid
Work Risk | Not Paid | Not Paid
Daycare and Social Benefits | Not Paid | Not Paid
INFONAVIT | Not Paid | Paid
Retirement | Not Paid | Paid
The type of unpaid day to be considered depends on the specific insurance branch being calculated within the employer-employee contributions.
### Add test for cfdi with disabilities.
target: 19.0
task-6066160
Forward-Port-Of: odoo/enterprise#116819This update resolves an error that occurred when opening payslips with multiple attachments. The fix prevents a data conflict that arose when deleting related documents, ensuring payslips can be opened and viewed correctly. It improves the stability of the payroll process.
Original PR description
Currently, an error occurs when a user opens a payslip. **Steps to Reproduce:** - Install the `documents_hr_payroll` module. - Go to `Payroll` > `Payslips` > `Payslips` and open an `existing payslip`…
Currently, an error occurs when a user opens a payslip. **Steps to Reproduce:** - Install the `documents_hr_payroll` module. - Go to `Payroll` > `Payslips` > `Payslips` and open an `existing payslip` or `create a new one`. - Add `two or more attachments` to the payslip. - Go to `Documents` and, in the left panel, navigate to `Company` > `Employees - YourCompany` > `Payroll YourCompany`, then `Move to Trash` all documents related to those `payslip attachments`. - Go back to `Payslips` and open the `same payslip` again. `ValueError: Expected singleton: hr.payslip(4, 4)` With [this commit], the attachment's "Add to Document" action allows creating a Document from a mail.thread record attachment. When the user deletes the documents related to the attachments and then opens the payslip again, the compute method runs to calculate the linked document ID for the payslip attachments and tries to retrieve attachments without documents [1]. The issue occurs when two or more attachments share the same payslip ID. While mapping the res_id of the attachments and grouping them by ID, the same payslip record is included multiple times for a single key [2] [3], which raises error here [4]. This commit ensures that the mapped res_id values are wrapped in a set, so duplicate IDs are removed and each payslip ID appears only once. [this commit]: https://github.com/odoo/enterprise/commit/5fa4b74a2345ddd4858585c5e9a780d1ca5add57 [1]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents/models/ir_attachment.py#L26 [2]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents/models/ir_attachment.py#L45 [3]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents/models/ir_attachment.py#L48 [4]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents_hr_payroll/models/hr_payslip.py#L74-L76 sentry-7494229711 Forward-Port-Of: odoo/enterprise#118033
This update resolves two minor bugs in the point-of-sale test suite. Specifically, it corrects how test results are evaluated and handles potential type mismatches, ensuring the tests accurately reflect the functionality of the POS system. This improves the reliability of the testing process.
Original PR description
..., l10n_es_pos, l10n_jo_edi_pos, l10n_br_edi_pos
---
Fix two bugs in the checkTicketData() test helper:
- Replace falsy check `!statement` with `!statement.length` to
correctly handle empty NodeList results from querySelectorAll,
as an empty NodeList is still truthy.
- Replace loose equality `ruleFound == rule.negation` with strict
equality `ruleFound === (rule.negation || false)` to avoid
unintended type coercion when `rule.negation` is undefined.
---
Task: https://www.odoo.com/odoo/project/1737/tasks/6147566
Forward-Port-Of: odoo/enterprise#118557
Forward-Port-Of: odoo/enterprise#114581This update resolves an error that prevented users from canceling draft POS orders. The issue stemmed from a recent code change that incorrectly returned order data. The fix removes this problematic code, restoring the ability to cancel draft orders as intended.
Original PR description
Currently an error is generated when the user tries to cancel a draft POS order as follows: - Install the `pos_enterprise` module with demo data - Open the register of `Furniture store` and select…
Currently an error is generated when the user tries to cancel a draft POS order as follows: - Install the `pos_enterprise` module with demo data - Open the register of `Furniture store` and select any product - Click on the `Upload` icon to save the draft order and go to the backend. - Navigate Orders > Orders > open Draft order - Click the `cog` icon and click `Cancel Order` >>> Error occurs This issue is caused by the recent refactor introduced in [1]. The `action_pos_order_cancel` action now returns the `order` (`pos.order` recordset) instead of default returning `None`. As a result, the `action` variable contains a `pos.order` recordset, and an error is raised at line [2] when `setdefault` is called on it, since `setdefault` expects a dictionary-like object. This commit fixes the above issue by removing the code that returns the `pos.order` object from the action. As a result, the action now behaves as expected and returns the default value (`None`). [1]: https://github.com/odoo/enterprise/commit/27f57036a1d0468efe6e68d7aceafe0f01b21f93 [2]: https://github.com/odoo/odoo/blob/48f93ca056633bd5cba36b66ee1008fb57ca666c/addons/web/controllers/utils.py#L24 Sentry-7354160052 Forward-Port-Of: odoo/enterprise#118035
This update resolves an issue caused by a recent change in the HR schedule layout. The update adjusts the view structure to ensure schedules display correctly within the new group layout. This improves the overall usability of the HR schedule feature.
Original PR description
Fixes the view breakdown caused by migrating the schedule separator to a group layout in the base hr view. Task: 6267822
This update allows users to efficiently edit analytics distribution data directly within asset records, mirroring the functionality available for journal items. This enhancement streamlines the process of analyzing asset performance and provides a more consistent user experience across Odoo Enterprise.
Original PR description
This commit fixes the multi-edit of analytics distribution field in assets form view. The multi-edit option was added to the analytics distribution widget, same as in the journal items. task-6218188 Forward-Port-Of: odoo/enterprise#119054 Forward-Port-Of: odoo/enterprise#118042
This update addresses a security vulnerability where test databases could incorrectly pass subscription checks on Odoo.com. The change adds a new verification step specifically for duplicated SAAS databases with a neutralized status, ensuring accurate subscription validation and preventing unauthorized access. This enhances the security and reliability of the Odoo Enterprise platform.
Original PR description
Odoo.com does not create a distinction between a production and duplicated SAAS database. This allows test databases to pass the check for subscription. This commit adds an additional check for duplicated SAAS databases with a neutralised status. task-6249752 Forward-Port-Of: odoo/enterprise#118281
This update resolves an issue that was slowing down map loading times by fixing a problem with how map pin data was being updated. The change ensures that map pins load more efficiently, especially in larger maps, by creating fresh copies of the data as needed. This results in a smoother and faster map experience for users.
Original PR description
Fixes a core model issue where `_filterUnlocatedRecords` destructively mutated `data.recordGroups` in place, making it impossible to evaluate subsequent progressive OSM coordinate arrivals. The baseline state is now preserved in `data.allRecordGroups` at load time, and a fresh copy is derived on each call. To support this progressive rendering, `MapPinListPopover` is equipped with a `useBus` subscription. This ensures that while the core controller subtree updates automatically, this isolated popover also stays in sync with the model. task-6255163 Forward-Port-Of: odoo/enterprise#118694
This update fixes an issue where flexible employee time off wasn't accurately displayed in the attendance calendar. Now, time off durations are correctly grayed out from midnight to 11 PM, aligning with expected behavior across day and week/month views. This ensures accurate tracking of flexible work schedules.
Original PR description
__ ## Short functional explanation of the error When setting a time off for an employee who has a flexible schedule, in the attendance app, on the calendar with the 'days' view. We can see that the…
__ ## Short functional explanation of the error When setting a time off for an employee who has a flexible schedule, in the attendance app, on the calendar with the 'days' view. We can see that the hours are grayed out from 8 hours to 16 hours. However, according to this message: https://www.odoo.com/mail/message/1027495005 "[...] the entire day of absence might not be represented as such, which is an issue (for example if a flexible employee with 8h/day takes a day off, the duration of the leave should be 1 day/8 hours but on the gantt view everything should be gray from midnight to midnight)". Moreover, when we select the Week or Month view on the calendar, the day off isn't grayed out. This comes from the fact that, for a flexible schedule, we consider that any time of the day can be a working hour; and we only grey out days in the calendar where no hour has been worked at all. Hence, the hours considered during a flexible day off should be from midnight to 23:59:59. ## Reproduction Steps 1. Go to an employee's profile and set their schedule to flexible. 2. Create a time off of a one-day duration for this employee. 3. Go to the attendance app and see the calendar. ### Expected behavior When clicking on the Day view, all hours from midnight to 11pm should be grayed out. When clicking on the Week/month view, the day of the time off should be grayed out. ### Unexpected behavior When clicking on the Day view, hours from 8am to 4pm are grayed out. When clicking on the Week/month view, the day of the time off isn't grayed out. ## Origin of the issue First, we only consider the leave if the resource is fully flexible, i.e if the employee has no working calendar set: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L546 However, if the schedule of the employee is flexible, the leave resource isn't considered as fully flexible, thus leading us to a leave from 8 am to 4 pm. Moreover, when processing flexible leaves, we return the unavailable intervals with the timezone of the employee: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L589-L592 Whereas when we process fixed leaves, we return the unavailable intervals under utc: https://github.com/odoo/odoo/blob/394a30f8a2814d460cfe220b5017e7ac95d8cddc/addons/resource/models/resource_calendar.py#L597-L601 This leads us to display problems: when the user is under European/ Brussels time in summer, the leave starts at 2 am and ends at 11pm, instead of starting at midnight. Note: after discussion with AJU, it has been agreed that the behavior should be the same on the Planning app. __ opw-6030212 Forward-Port-Of: odoo/enterprise#118832 Forward-Port-Of: odoo/enterprise#112482
This update fixes a technical issue that prevented the system from correctly processing payrolls with previously recorded negative amounts. The fix involved correcting references to these amounts and removing unnecessary code, ensuring accurate paycheck calculations and preventing errors.
Original PR description
Steps to produce: - create a previous payslip with negative amount - create a payslip for current month - click on the warning to apply negative amount - you get an error or a traceback because it's referencing an input which is removed from the system and migrated to other input Fix: - corrected the reference to negative net - removed content of the method `_generate_payslip` as it's not used and referencing removed inputs task-id: 6240163 Forward-Port-Of: odoo/enterprise#119143 Forward-Port-Of: odoo/enterprise#118144
This update resolves an issue where the Timesheet Assistant was incorrectly matching events to projects with disabled timesheets. The changes ensure the assistant only considers projects with active timesheets, improving data accuracy and preventing irrelevant suggestions. This update was implemented across the entire system.
Original PR description
Currently, the Timesheet Assistant (ActivityWatch) can match events to projects or tasks that have timesheets disabled, either via Custom Rules or Historical Memory.
This commit resolves the issue across the entire pipeline:
- Backend: Updated `resolve_assistant_models_targets` to efficiently filter out records where `allow_timesheets` is False using a search domain.
- Frontend: Updated the `loadData` JS pipeline to intercept and wipe any project/task IDs rejected by the backend, ensuring they cleanly fall back into a single "Unmatched" group.
- Views: Added the `[('allow_timesheets', '=', True)]` domain to `project_id` and `task_id` fields in `aw.rule` views to prevent users from creating invalid rules.
Task: 6267401This update resolves a technical error that prevented users from accessing the assistant frequency view within the Odoo Enterprise application. The issue stemmed from a missing context variable, which caused an error when the view attempted to display optional settings. The fix adds a necessary context variable and a test to ensure this functionality remains stable.
Original PR description
Steps: 1- install timesheet_grid 2- navigate to assistant > configuration > local assistant rules => TypeError: Cannot read properties of undefined (reading 'list_optional_show') Source: After commit https://github.com/odoo/odoo/commit/764e7c2a951eb775e7aa2579f4e0774e382a385b, context.list_optional_show was added, but context is undefined in the assistant frequency viewer Solution: add context as an empty object add a test to detect regressions on openinig the frequency viewer task-6251619
This update significantly improves the performance of the VAT Books ES report by processing invoices in batches instead of loading everything into memory at once. This prevents crashes and slowdowns caused by excessive memory usage, especially when dealing with large invoice volumes. The change ensures the report generates reliably and efficiently.
Original PR description
### Description of the issue/feature this PR addresses: This PR introduces batch processing to the VAT Books ES (Libros de IVA) report generation. When attempting to export the report for periods…
### Description of the issue/feature this PR addresses: This PR introduces batch processing to the VAT Books ES (Libros de IVA) report generation. When attempting to export the report for periods containing a massive volume of invoices, the ORM cache continuously accumulates records, leading to severe memory consumption. By implementing batching and explicitly clearing the environment cache, use memory use will remain stable and efficient. ### Current behavior before PR: Generating the VAT Books report loads all account move lines into memory at once. Because the ORM cache is never cleared during the iteration, RAM usage spikes continuously. On databases with tens or hundreds of thousands of invoices in a single period, this leads to significant performance degradation, worker timeouts, or complete Out-Of-Memory (OOM) crashes. ### Desired behavior after PR is merged: The report engine now splits the recordset into manageable batches (e.g., 50,000 accounts per batch). After processing each chunk to extract the income and expense line values, invalidate_model() is called to flush the ORM cache related to the searched records. This frees up memory continuously, keeping the server's RAM usage flat and allowing the successful export of massive datasets without crashing. ### Benchmark: The model is iterating through ~1.1M account move lines when generating the full report. For Memory: | # Input Data | Before PR | After PR| | -------- | -------- | -------- | | ~77,000 account move lines | 385 MB | 666 MB | | ~340,000 account move lines |1.2 GB | 1.5 GB | | ~1.2M account move lines | MemoryError | 1.5 GB | For Speed: | # Input Data | Before PR | After PR| | -------- | -------- | -------- | | ~77,000 account move lines | 32s | 12s | | ~340,000 account move lines | 2:29min | 1:11min | | ~1.2M account move lines | MemoryError | 4:11min | ### Reference opw-6037414 ----------------------------------------------------------------- I confirm I have signed the CLA and read the PR guidelines at [www.odoo.com/submit-pr](http://www.odoo.com/submit-pr) Forward-Port-Of: odoo/enterprise#118903 Forward-Port-Of: odoo/enterprise#116139
This update fixes a bug preventing the use of the 'NABN' document type for vendor credit notes in the GT accounting module. Previously, this option was unavailable, which caused issues with processing electronic payments. Now, users can correctly select 'NABN' when reversing vendor credit notes, ensuring accurate GT accounting.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Navigate to Invoicing > Vendors > Bills. - Create a new vendor bill. - Observe that `GT Document Type`…
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Navigate to Invoicing > Vendors > Bills. - Create a new vendor bill. - Observe that `GT Document Type` includes `NABN - Nota de Pago Electrónica` option. - `Confirm` the bill. - Click `Credit Note`, add a reason, and click `Reverse`. - Observe the available options in the `GT Document Type` field. **Observation:** The `NABN - Nota de Pago Electrónica` option is not available for vendor credit notes (`in_refund`), even though `NABN` is a GT-specific credit note document type. **Root Cause:** At [1], `NABN` is added for vendor bills (`in_invoice`, `in_receipt`) instead of vendor credit notes (`in_refund`). **Fix:** This commit ensures users can correctly select `NABN - Nota de Pago Electrónica` on GT vendor credit notes. [1]: https://github.com/odoo/enterprise/blob/c7fa8c9c6f6830f5702fab4f6efaf3ac33f7fe72/l10n_gt_edi/models/account_move.py#L159-L160 opw-6252256 Forward-Port-Of: odoo/enterprise#119259 Forward-Port-Of: odoo/enterprise#118711
This update resolves an issue where the Executive Summary report would fail when the date range option was disabled. The fix ensures the report uses the fiscal year's start date instead, preventing a calculation error and ensuring the report always displays correctly. This improves the report's reliability for users.
Original PR description
## Steps to Reproduce: 1. Install the Accounting module. 2. Go to Accounting > Reporting > Executive Summary. 3. Activate debug mode. 4. Click on the gear icon at the top. 5. In the "Options" tab,…
## Steps to Reproduce: 1. Install the Accounting module. 2. Go to Accounting > Reporting > Executive Summary. 3. Activate debug mode. 4. Click on the gear icon at the top. 5. In the "Options" tab, disable the "Date Range". 6. Open the report again. ## Error: `TypeError - unsupported operand type(s) for -: 'datetime.date' and 'NoneType'` ## Cause: At [1], when the "Date range" option is disabled in the summary report, `date_from` becomes None. The NDays expression still computes `date_to - date_from` at [2], which raises a TypeError because subtraction between a datetime and NoneType is not supported. ## Fix: This commit takes the fiscal-year's start date, when the date-range feature is disabled. [1] - https://github.com/odoo/enterprise/blob/a9cadd93b849375edfcc7fd04612d9eb8787043b/account_reports/models/account_report.py#L564-L570 [2] - https://github.com/odoo/enterprise/blob/a9cadd93b849375edfcc7fd04612d9eb8787043b/account_reports/models/executive_summary_report.py#L15-L16 sentry-7455506965 Forward-Port-Of: odoo/enterprise#119162 Forward-Port-Of: odoo/enterprise#116888
This update resolves an issue where Luxembourg tax reports were incorrectly generating company registry numbers instead of the agent's RCS number when a natural person accountant was not linked. The fix ensures accurate XML declaration for Luxembourg tax authorities, preventing report rejection. This improves compliance and avoids potential delays in tax processing.
Original PR description
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person…
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person (independent accountant) with no business registration number — i.e. `l10n_lu_agent_rcs_number` is left empty on the agent partner. * Go to the tax report and generate the XML declaration. **Observed behavior:** * The `<Agent><RCSNbr>` field in the generated XML contains the company's own `company_registry` value instead of `NE`. * The file is rejected by the Luxembourg tax administration. **Cause:** * In `l10n_lu_generate_xml.py`, the `agent_rcs_number` template value was built with a plain `or` chain: `agent.l10n_lu_agent_rcs_number or company.company_registry or "NE"` * When an agent is set but has no RCS number (natural person), the fallback incorrectly continued to `company.company_registry` instead of stopping at `"NE"`. **Fix:** * Use a conditional expression so that `company.company_registry` is only used as a fallback when **no agent is linked** to the company: `(agent.l10n_lu_agent_rcs_number if agent else company.company_registry) or "NE"` opw-6044689 Forward-Port-Of: odoo/enterprise#112968
Features or functions removed from Odoo
This update removes a previously used JavaScript file related to appointment scheduling. This change was made because the functionality was already available in another part of the system, eliminating a duplicate and simplifying maintenance. This ensures consistent performance and reduces potential code complexity.
Original PR description
Purpose of this PR: Since html_editor/static/src/utils/regex.js has been removed as it contained redundant logic already present in link/utils. community-https://github.com/odoo/odoo/pull/265767 task-6199269
This update removes a redundant 'today' date filter from the 'My Map' menu. As a new date selection filter is being implemented, this default filter is no longer necessary, streamlining the user experience. This change prepares the system for the upcoming date filtering functionality.
Original PR description
In this commit, we remove the default filter on "today" in the "My Map" menu. As we will introduce a date selection filter, this filter does not make sense anymore. task-6273672
Code cleanup and technical improvements
This update addresses technical debt by migrating from outdated Owl 3 hooks to the newer Owl 3 alternatives. Specifically, unused code related to attendance Gantt charts and payroll change detection has been removed, streamlining the system and improving performance.
Original PR description
As part of the Owl 3 migration, replace deprecated onRendered hooks with the appropriate Owl 3 alternatives. In hr_attendance_gantt, remove the obsolete loadHelper logic since it is no longer used. replace the payRunId change detection in hr_payroll with a useEffect.
This update aligns the Knowledge and Sign applications with a new, standardized component for managing form status indicators. This refactoring eliminates redundant code and ensures a consistent user interface across Odoo Enterprise, improving maintainability and reducing potential errors. The previous custom status indicator in the Sign module has been removed.
Original PR description
This PR adapts the `knowledge` and `sign` applications to use the newly refactored, model-agnostic `FormStatusIndicator` component from the `web` module. Specifically, it updates the component calls to pass the newly required properties (`isDirty`, `isValid`, `isNew`, `save`, `discard`) instead of the `RelationalModel`. In `sign`, the custom `SignStatusIndicator` implementation has been removed and replaced by extending the core `FormStatusIndicator`, eliminating duplicated logic and ensuring consistent behavior with the rest of the application. **Related Community PR:** https://github.com/odoo/odoo/pull/264066 **Task:** 4422555
This update refactors several Odoo addons (including marketing automation, MRP, POS, and planning) to use a new proxy-based approach instead of `useState`. This change improves the underlying architecture and prepares the system for future development. It impacts multiple modules within the enterprise suite.
Original PR description
In Owl3, uses of `useState` or replace with `proxy`. This commit changes all those uses for addons in the range [m..!w]. *: marketing_automation,mrp_workorder,planning,pos_appointment,pos_blackbox_be,pos_enterprise,pos_iot_six,pos_platform_order,pos_restaurant_appointment,pos_sale_planning,pos_tyro,pos_urban_piper,quality_mrp_workorder,room,sale_planning,sale_renting,sale_timesheet_enterprise,sign,sign_emsigner,social,social_linkedin,social_push_notifications,social_twitter,social_youtube,spreadsheet_dashboard_edition,spreadsheet_edition,spreadsheet_sale_management,stock_barcode,stock_barcode_mrp,timer,timesheet_grid,timesheet_grid_hr_attendance,voip
This update modernizes the bank reconciliation widget by replacing outdated React techniques with a more efficient system. Specifically, it removes the use of `useLayoutEffect`, which is now deprecated, and utilizes signals for automatic data updates, resulting in a smoother user experience. This change improves performance and aligns with current best practices.
Original PR description
Replace useState + useLayoutEffect with computed/signal from OWL3: - accountMoveLines, linesToReconcile, suspenseAccountLine, and reconciledLineName are now computed signals that re-derive automatically when line_ids changes, removing the need for _updateLinesState() and its useLayoutEffect trigger - isUnfolded is a plain signal (writable boolean) - Drop fold/unfold which were unused. WHY: useLayout effect is deprecated NOTE: This widget was tested with the tour `test_tour_bank_rec_widget` but may still contain some errors
This update addresses a technical issue related to the Gantt chart library by replacing an outdated component. This change ensures the Gantt chart continues to function correctly and avoids potential future compatibility problems. It's a routine maintenance update.
Original PR description
Replaces useLayoutEffect with [xxx] WHY: UseLayoutEffect is deprecated in OWL3
This update removes an outdated method of passing data through notifications, streamlining the notification process and simplifying the underlying code. This change improves efficiency and reduces unnecessary data access, leading to better performance and maintainability.
Original PR description
Purpose: get rid of "msg_vals" added in various notification methods. Its purpose is to avoid browsing message records when values are available to avoid redundant accesses (see https://github.com/odoo/odoo/pull/32404 ). This is now quite an old school approach, and with time and overrides part of its benefits were lost. In this task we remove message values propagation, using message record as source of values. This allows to simplify API of several methods as well as code. Some query counters are higher, as we have to fetch some values that were previously found in message values. Next step is to check if cache usage can be improved in order to avoid queries if those are annoying or might create performance issues. Task-4845982