Daily updates from Odoo
Monday, March 23, 2026
111 changes
20 changes
Resolved issues and error corrections
This update resolves an error that occurred when activating the 'hr_expense_stripe' module with unsupported currencies (like INR). The fix prevents the creation of a problematic journal, ensuring the invoicing dashboard can be opened without errors. It now defaults to the company's currency for new databases.
Original PR description
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to…
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to reproduce: (19.0) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` - Create New company > Set `Country` and `Currency` (eg: India and INR) > Switch to New company > Open `Invoicing` you will get the error. Steps to reproduce: (saas-19.1) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` > Open `Invoicing` you will get the error. Traceback: `ValueError: Expected singleton: res.currency()` In this [PR], the behavior is such that if `company.stripe_currency_id` is not set, we do not create the "Stripe Issuing". In 19.0, `@template` was executed after the post-init hook, and we were preventing the creation of the [journal] at that stage. However, when a new company is created, the template data is automatically loaded for companies with a matching chart of accounts. As a result, the `stripe_issuing_journal` is created, which leads to the error. However, in saas-19.1, due to recent improvements in a [commit], the `@template` will now loads data for companies without post init hook. As a result, the `stripe_issuing_journal` is being created, and we are encountering an error. Solution: - The`Stripe Issuing` journal will no longer be created on installing the module. - For existing databases, we will use the company currency as a fallback value to ensure that a valid currency is applied. [PR]: https://github.com/odoo/enterprise/pull/96271 [journal]: https://github.com/odoo/enterprise/blob/fea009f98885a97439edfea75376b7323c8c9a03/hr_expense_stripe/models/res_company.py#L186-L187 [commit]: https://github.com/odoo/odoo/pull/228950/changes/21fd14ed5e8bdd2cf203d466069437a62a87f2bd sentry-7284934493 Forward-Port-Of: odoo/enterprise#108436
This update resolves an issue where the topbar menu wasn't correctly updated when a menu was opened using the AI Agent. The fix ensures that the topbar menu accurately reflects the currently active menu after an AI Agent interaction, improving the user experience. This change was driven by a bug fix (Task-6017607).
Original PR description
Purpose: -------- When a menu (view) was opened through an AI Agent, the menu in the topbar was not updated. This commit fixes this behaviour by setting the menu when the menu's action has been loaded Task-6017607 Forward-Port-Of: odoo/enterprise#109929
This update automatically calculates and transmits the necessary commission deductions for Swiss payroll (ELM) based on employee data. This ensures accurate tax reporting and compliance with Swiss regulations, streamlining the payroll process. The change corrects a previous issue related to commission calculations.
Original PR description
task-6050810 Forward-Port-Of: odoo/enterprise#111143
This update resolves a technical error that prevented invoices with the ICBPER tax code in Peru from generating correctly. The fix adjusts a configuration setting to avoid a data structure mismatch, ensuring invoices process smoothly and accurately. This improves the reliability of invoice generation for Peruvian clients.
Original PR description
**Steps to reproduce:** 1. Install module `l10n_pe_edi`. 2. Switch company to PE. 3. Create a tax: - Name: ICBPER - Amount type: Fixed - Code: ICBPER - Amount: 0.5(e.g.) - Set the tax group to ICBPER…
**Steps to reproduce:**
1. Install module `l10n_pe_edi`.
2. Switch company to PE.
3. Create a tax:
- Name: ICBPER
- Amount type: Fixed
- Code: ICBPER
- Amount: 0.5(e.g.)
- Set the tax group to ICBPER (In Advance Option)
4. Create a invoice and add a product with ICBPER tax.
5. Post the invoice and click "Process Now" (at header).
**Issue:**
Processing the invoice raises:
AttributeError: 'dict' object has no attribute '_get_downpayment_lines'
**Cause:**
When `fixed_taxes_as_allowance_charges` is True, `_setup_base_lines()` calls `_turn_emptying_taxes_as_new_base_lines()`, which splits fixed taxes (e.g., ICBPER) into separate base lines.
During this process, `base_line['record']` is no longer the original `account.move.line` record. Instead, it becomes a dictionary containing record under `base_line['record']['record']`.
- With the flag enabled: `base_line['record']` -> dict `line._get_downpayment_lines()` -> AttributeError
- With the flag disabled: `base_line['record']` -> `account.move.line``line._get_downpayment_lines()` -> works correctly
The Peru EDI implementation directly accesses `base_line['record']` expecting an `account.move.line`. The the nested dict structure causes the crash during file generation.
**Solution:**
Override `_add_invoice_config_vals()` to explicitly set `fixed_taxes_as_allowance_charges = False`
- Add test to ensure invoices with ICBPER fixed taxes generate XML without error
**opw-5809939**
Forward-Port-Of: odoo/enterprise#108638This update resolves several issues impacting the Field Service planning feature, specifically related to shift generation, data handling, and user interface display. The changes ensure accurate state management during shift duplication and improve the overall usability of the planning tools.
Original PR description
## [FIX] planning_field_service*,worksheet: fixes follow-up This commit fixes and improves field service feature in planning to be sure to not have any regression compared to the previous field…
## [FIX] planning_field_service*,worksheet: fixes follow-up This commit fixes and improves field service feature in planning to be sure to not have any regression compared to the previous field service app. In detail, this commit will: - better handle SOL generation - fix buttons visibility, display name, multi-company issues - fix mix up demo and data - auto install when sale timesheet and field service - display the first slot for today in the stat button - handle multi-company issue in slot conflicts Make partner phone readonly if no Contact access. Hide the Serial/Lot products from the shift catalog if the user has no inventory access - display view itinerary label in mobile - set role in field service product - fix the domain of SO stat buttons related to shifts - fix the default groups of "Planning By ..."" actions. - use a custom search view for 'resource_ids' in kanban of shifts - ask to switch in employee portal - hide by default some fields in list view of shift - avoid recomputing when a worksheet property changed - display message to design worksheet in desktop only - display plan intervention in ticket - recompute allocated hours when break time changed - rename Publish & send button into Publish in form view of planning.slot model - display full form in my planning only ## [FIX] planning: manage state in copy_data Before this commit, when the shift is duplicated, the state is not reset as expected. This commit sets copy=False on state field of planning.slot model, to handle that in copy_data when the shift is splitted because in that case we want to keep the state instead of resetting it. ## [FIX] planning: display notification error when save as template a template Before this commit, since the Save as template button is in the cog menu, it is still displayed even if shift has already generated a shift template. This commit will display a notification in the action of that button when there is already a template linked to that shift. ## [FIX] planning: display planned dates in display_name when empty Before this commit, the display_name of a shift could be empty and displays "Unamed" in the breadcrumb due to project, task, customer and role can be unset on the shift. This commit will display the planned dates of shift when the other fields used in the compute of display name are unset. However, the planned dates are not displayed in the display name if the view is gantt or calendar because the planned dates are already displayed and would be redundant. ## [FIX] worksheet: hide section when separator is folded Before this commit, when the definition of a worksheet defines 2 sections folded by default with some properties inside of each one and the worksheet template is used for a shift, if the user just unfolds one section to fill in just this one and lets the other section unfolded, then the properties in the both sections are displayed in the portal of the shift even if the second section is folded. The reason is because the value of the second separator is not in the properties of the shift because it is untouched. This commit checks if the separator is by default folded if its value is not in the properties of the shift. task-6020304 Co-Authored: Xavier Bol (xbo) <xbo@odoo.com>
This update corrects a visual discrepancy between how the AI livechat snippet is displayed in the editor and how it appears to users. The fix ensures the snippet's appearance matches the real-time experience, resolving a rendering problem caused by mismatched code structures. This improves the overall user experience for AI livechat setup.
Original PR description
Scenario: - add ai livechat snippet block - switch to mobile - enable "Fallback Button" - save Result: the rendering is different between edition and real usage of AI livechat snippet. Cause: structure and classes don't match Fix: make the structure and classes match. opw-5458575 pr note: I copied `ai_website_livechat.AILivechatComponent` in `ai_website_livechat.s_ai_livechat_edit` but it might make more sense to just render the owl widget with a class that neuter the AI (this way we don't need to update both template at each change) Forward-Port-Of: odoo/enterprise#109569
This update fixes a potential issue where payroll calculations were being applied to outdated payslips, which could have impacted data accuracy. The change now limits these calculations to ongoing payslips, ensuring more precise and reliable payroll processing. This improves the overall stability and accuracy of the HR module.
Original PR description
Before this commit, `_compute_basic_net` was not limited to specific payslips, potentially affecting thousands of records and even more of `hr.payslip.line` records. This commit restricts the compute to ongoing payslips. task-6022499 Forward-Port-Of: odoo/enterprise#111219 Forward-Port-Of: odoo/enterprise#110069
This update fixes an issue where project timesheets didn't accurately reflect changes in manufacturing employees. The fix automatically updates the AAL (analytic accounting line) associated with the work center when an employee is switched, ensuring accurate timesheet calculations and reporting. This improves the reliability of project cost tracking.
Original PR description
### Steps to reproduce: - Create an MTO product and another Service product that create a project and task - Create a quotation with both products - Create two employees with different hourly cost - Go to Manufacturing order - Configure an employee to manufacture the product at a work station. - Observe the project dashboard - Go back to the MO and change the employee on the work station - Notice the project dashboard Timesheets section doesn't have any change on the amount ### Cause: This is happening because when changing the employee we don't modify anything in the AAL linked to the work station. As we only modify the AAL when the duration change. ### Fix: We call _create_analytic_entry when we change the employee on the work station to change the amount and the employee_id for the AAL. opw-5939321 Forward-Port-Of: odoo/enterprise#111040 Forward-Port-Of: odoo/enterprise#109695
This update resolves an issue where payrun creation failed for employees with contracts starting mid-period. The fix ensures the system correctly handles contract start dates, preventing errors and allowing accurate payroll processing. This improves the reliability of pay runs for new hires.
Original PR description
An error is thrown when an employee's contract starts mid-period. ```py Invalid Operation Wrong python code defined for: - Employee: Cesar Osbaldo Cruz Solorzano - Version: False - Payslip: Payslip -…
An error is thrown when an employee's contract starts mid-period.
```py
Invalid Operation
Wrong python code defined for:
- Employee: Cesar Osbaldo Cruz Solorzano
- Version: False
- Payslip: Payslip - Cesar Osbaldo Cruz Solorzano - 01/16/2026 - 01/31/2026
- Salary rule: Integrated Daily Wage (Base) (INT_DAY_WAGE_BASE)
- Error: AttributeError("'bool' object has no attribute 'year'") while evaluating
'\nresult = round(payslip.l10n_mx_integration_factor * payslip.l10n_mx_daily_salary, 4)\n
```
Steps to reproduce:
1. Install `l10n_mx_hr_payroll` modules
2. Switch to ESCUELA KEMPER URGATE company
3. Go to Employees and open Cesar Osbaldo Cruz Solorzano
4. Go to Payroll tab, change the start date of contract to 01/10/2026 and save
5. Go to Payroll > Payslips > Payslips and create a new pay run
6. Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Monthly' and Period '01/01/2026 -> 01/31/2026'
7. Click on Continue, select Cesar and click on Select
8. An error is thrown
Problem:
In `_compute_integration_factor` method, `_get_first_contract_date` is called with context `before_date`, it returns `False` as the contract starts after the payslip period. This causes an error when trying to access the `year` field of `start_date`.
Solution:
Add a fallback to call `_get_first_contract_date` without context in case the first call returns `False`.
target: saas-18.4
task-6034836
Forward-Port-Of: odoo/enterprise#111007
Forward-Port-Of: odoo/enterprise#110568This update resolves issues where invoices with global discounts or down payments were incorrectly sending negative values to the Sinvoice system, causing errors. The fix now properly handles these scenarios and includes support for uploading note lines on invoices, ensuring accurate data transmission for Vietnamese tax reporting.
Original PR description
Previously, the invoice logic did not properly handle the following scenarios: - Global discount: when a global discount was applied, negative values were sent to Sinvoice, resulting in a BAD_REQUEST_ITEM_VALUES_NEGATIVE error. - Down payment: when an invoice included a down payment to deduct the amount, negative values were sent to Sinvoice, triggering the same BAD_REQUEST_ITEM_VALUES_NEGATIVE error. - Note lines: note lines on the invoice were not being uploaded/included in the invoice submission. This commit fixes the handling of global discounts and down payments by ensuring negative values are properly transformed before being sent to Sinvoice, and adds support for uploading note lines in the invoice. task-5875158 Forward-Port-Of: odoo/odoo#254796 Forward-Port-Of: odoo/odoo#251913
This update ensures that manufacturing orders are created separately for MTO products that share components. Previously, only one MO was generated, leading to tracking issues. Now, each shared component will have its own dedicated manufacturing order, improving inventory accuracy and production management.
Original PR description
Currently, when a user creates a Sale Order for MTO products that share the same component (which itself has a BOM), the system does not create a separate child MO for each manufacturing order. ##…
Currently, when a user creates a Sale Order for MTO products that share the same component (which itself has a BOM), the system does not create a separate child MO for each manufacturing order. ## Steps to produce: - Install Sales and Manufacturing - Go to Settings and turn on Replenish on Order (MTO). - Create products 'Wooden Arrow' and 'Wooden Rod' with a BOM that includes: - 'Stick', which itself has a BOM with 'Raw stick'. - On each product page, go to Inventory and enable the MTO route, except for 'Raw Stick' . - Create a Sale Order for Wooden Arrow and Wooden Rod for Customer 'Administrator'. - Confirm the Sale Order. - Go to Manufacturing > Open and check both Manufacturing Orders. ## Observed Behavior: Currently, the manufacturing order for 'Wooden Arrow' has a child MO, but the order for 'Wooden Rod' does not. The child MO under 'Wooden Arrow' produces two sticks at once. However, each manufacturing order should have its own separate child MO so that every item is produced and tracked individually. ## Root cause: The issue happens because when a Sale Order is confirmed, [_run_manufacture](https://github.com/odoo/odoo/blob/7c7c6663e28974834d1569b27605f6ce400c7b16/addons/mrp/models/stock_rule.py#L81-L120) is called. This method creates a new MO or updates an existing one based on the domain returned by `_make_mo_get_domain` [1]. For 'Wooden Arrow' and 'Wooden Rod; new MOs are created because no existing MO matches their BOM ID, product ID, or reference. They are added to `new_productions_values_by_company` [2], which is then used to create the MOs [3]. When `_run_manufacture` runs for 'Stick', it is triggered twice since both MOs require it as a component. The first time, no MO matches the domain, so a new one is created. The second time, the domain matches the existing MO (same BOM ID and product ID), so that MO is updated instead [4]. Because of this, `new_productions_values_by_company` is not filled again, and no second child MO is created. [1]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L146-L165 [2]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L98-L103 [3]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L113-L115 [4]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L105-L110 ## Solution: To resolve this issue, the domain has been tightened to include the parent production group ID. Since the parent MO’s group ID is passed through the procurement variable when `_run_manufacture` is executed for its component products, this group ID can be used to ensure the correct MO is matched. **Why modify the existing test case?:** With this change, in the `test_sale_mrp_pickings` test case, a new child MO for 'Stick' is created under the MO for 'Arrow' instead of modifying another parent MO for 'Stick'. The test case has been updated accordingly. (Confirmed the new behavior with CRL and TAGO) opw-5480133 Forward-Port-Of: odoo/odoo#248229
This update fixes an issue where the phone number input field on mobile devices was difficult to edit due to overlapping buttons. The fix hides the text labels from the utility buttons, allowing the input field to take up the full screen width and improving the user experience. This ensures users can easily and accurately enter phone numbers on their mobile devices.
Original PR description
Steps to reproduce: 1. Install `contacts` 2. Create an individual contact with a phone number 3. Try to edit the phone number on the mobile Issue: - Unable to edit in mobile view Cause: - On mobile…
Steps to reproduce:
1. Install `contacts`
2. Create an individual contact with a phone number
3. Try to edit the phone number on the mobile
Issue:
- Unable to edit in mobile view
Cause:
- On mobile devices, the utility buttons (Call, SMS, WhatsApp) inside the phone widget consume significant horizontal space. Due to the flex layout, this forces the actual phone input field to shrink too much, making it hard/impossible to view or edit the number.
Solution:
- Hide the text labels of the utility buttons to save space, showing only the icons
- make input's width 100% on mobile screens in partner form
<table>
<thead>
<tr>
<th>Before</th>
<th>After</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">
<img
src="https://github.com/user-attachments/assets/a620d417-119e-4e28-a62b-f63031e72598"
alt="Before"
width="500"
/>
</td>
<td align="center">
<img width="500" height="354" alt="image" src="https://github.com/user-attachments/assets/6adc4c77-767d-491d-a468-8463c0f77666" />
</td>
</tr>
</tbody>
</table>
opw-5489021
Forward-Port-Of: odoo/odoo#250256
Forward-Port-Of: odoo/odoo#246295This update fixes an issue where consolidated POS invoices were incorrectly showing a zero payable amount. MyInvois requires the total invoice amount to be accurately reflected, regardless of prior payments. This change ensures the payable amount aligns with MyInvois API requirements, resolving a compatibility problem.
Original PR description
For POS consolidated invoices, the PrePayment Amount was mapped to the payment linked to the document. This incorrectly decreased the Total Amount Payable to 0, since POS orders are already paid at the counter. MyInvois tax officer and helpdesk requires that the Total Amount Payable (cbc:PayableAmount) to reflect the total amount of the issued e-document , regardless of prior payments. This commit forces the PaidAmount to 0 for consolidated documents, ensuring the PayableAmount correctly matches the TaxInclusiveAmount as expected by the MyInvois API. task-[6021698](https://www.odoo.com/odoo/all-tasks/6021698) Forward-Port-Of: odoo/odoo#254183 Forward-Port-Of: odoo/odoo#253499
This update resolves issues with the XML structure generated for Spanish VAT invoices (l10n_es_edi_facturae). Specifically, it now correctly calculates and formats tax outputs, including rounding for accurate tax aggregation. This ensures compliance with Spanish tax regulations and improves the reliability of invoice data.
Original PR description
- Adjusting invoice-level `<TaxesOutputs>` nodes to be generated per tax rather than per line - Enabling rounding for invoice-level tax data aggregation - Adding a second rounding test derived from bug ticket task-6009108 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253305
This update resolves a problem where invoices with specific fixed tax configurations (related to 'vidange/consigne') were failing Peppol validation checks. The fix adjusts how fixed taxes are handled during invoice generation to ensure compliance with Peppol standards for VAT breakdowns. This prevents invoices from being rejected by external systems.
Original PR description
**PROBLEM** Here is the client use case: The client uses fixed tax to do 'vidange/consignage'. When selling a product with a 'consigne/vidange', they add a fixed tax which amount correspond to the…
**PROBLEM** Here is the client use case: The client uses fixed tax to do 'vidange/consignage'. When selling a product with a 'consigne/vidange', they add a fixed tax which amount correspond to the 'consigne/vidange'. When returning the 'consigne', you would create an invoice line, with a product with a price of 0, negative quantity,a 0% tax and the fixed tax for the 'consigne'. When an invoice contains such lines, it fails peppol validations. **STEP TO REPRODUCE** 1. Create a fixed tax used for 'vidange/consigne'. 2. Create an invoice, with a line with unit price of 0, negative quantity, a 0% tax and the fixed tax for the 'consigne'. 3. Send the invoice using peppol, use a validator to validate the xml and notice you get the following errors: [BR-E-01] [BR-E-08]. **CAUSE** Fixed tax (like the one used for vidange) are aggregated in new invoice lines by the function `_ubl_turn_emptying_taxes_as_new_base_lines()`. Let say we have the following invoice: line 1: qty=2, unit_price=3, taxes: 21% & vidange(fixed tax of 1). line 2: qty=-1, unit_price=0, taxes: 0% & vidange. After calling `_ubl_turn_emptying_taxes_as_new_base_lines()`, we got: line 1: qty=2, unit_price=3, taxes: 21%. line 2: qty=-1, unit_price=0, taxes: 0%. line 3: qty=1, unit_price=1(amount of the fixed tax), taxes:None. When generating the VAT breakdown, we have 2 line will end up being tax exempted (line 2 and 3). Because the `tax_exemption_reason` differs, they will not be merged in the same entry in the breakdown, which break the constraint of peppol saying we can only have one VAT breakdown with code 'Exempt from tax'. Line 2 reason comes from: https://github.com/odoo-dev/odoo/blob/de22093ee225df499b2de80e1f07dd281ac686bc/addons/account_edi_ubl_cii/models/account_edi_common.py#L271-L274 opw-5912986 Forward-Port-Of: odoo/odoo#254875 Forward-Port-Of: odoo/odoo#250413
This update resolves an issue preventing Odoo from correctly generating UBL invoices for Hungarian partners. The fix automatically builds the VAT number from the Hungarian Tax Number (Adószám) when the country code prefix isn't present, ensuring invoices meet NAV requirements and avoid rejection.
Original PR description
Problem --------- When building the UBL, invoices with Hungarian partners get hit with the following constains: "The VAT of the [role] should be prefixed by the country code". However, Hungary allows for VAT numbers that do no start with the country code. Every Hungarian business is assigned a Tax Number (Adószám) that follows a fixed 11-digit format: NNNNNNNN-Y-CC. Solution --------- Build the VAT number from the Domestic Tax Number if it is not the case. no-task --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253663
This update ensures that all worked days on payslips are correctly linked to a work entry type. Previously, creating a public holiday without this link prevented payslips from being generated. This change makes the process more reliable and accurate for payroll processing.
Original PR description
All worked days lines in payslips should be linked to a work entry type. If we create a public holiday without linking it to a work entry type, it won't be possible to generate a payslip. Making the field required fixed the issue. task-6044274 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a bug where customers could modify the global discount line within optional sections of sales orders. The change prevents unauthorized edits to this discount, ensuring accurate order pricing and preventing potential revenue discrepancies. This resolves issue OPW-6045297.
Original PR description
Issue: --- Due to this issue global discount line can be edited by customer. #### Steps to reproduce: 1- Create a SO with SOLs and add a optional section. 2- Add a global discount under optional section. 3- Preview the SO. The quantity of discount can be edited. Cause and Fix: --- In `_can_be_edited_on_portal` we are not excluding the global discount line from being editable. We could fix that by excluding line with company discount product from being editable. opw-6045297 Forward-Port-Of: odoo/odoo#254870
This update fixes visual and functional issues within the SelectMenu component, including highlighting search results and resolving glitches related to dropdown behavior and placeholder display. The changes enhance the user experience and ensure consistent styling across the Odoo interface. This resolves a reported bug and improves the overall usability of the SelectMenu.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251992
This update fixes an issue where the VAT Return (CZ) report was incorrectly displaying negative amounts when invoices with VAT 24 or 23 tax grids were created. Previously, the report showed incorrect VAT calculations. This change ensures accurate VAT reporting for Czech companies using the l10n_cz module.
Original PR description
With l10n_cz company: 1. Create some invoices using the VAT 24 or VAT 23 tax grid on an invoice line containing an amount in credit. 2. Go to the VAT Return (CZ) report 3. The amount shown will be negative instead of positive, which goes against what the report should show. Missed by 17a6117ed88c29b5bc4db0c872bcdbc109a7d98b opw-5978183 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#252243
23 changes
Resolved issues and error corrections
This update resolves an error that occurred when activating the 'hr_expense_stripe' module with unsupported currencies (like INR). The module will no longer attempt to create a specific journal, and existing company currencies will now be used as a fallback, ensuring the invoicing dashboard functions correctly.
Original PR description
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to…
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to reproduce: (19.0) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` - Create New company > Set `Country` and `Currency` (eg: India and INR) > Switch to New company > Open `Invoicing` you will get the error. Steps to reproduce: (saas-19.1) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` > Open `Invoicing` you will get the error. Traceback: `ValueError: Expected singleton: res.currency()` In this [PR], the behavior is such that if `company.stripe_currency_id` is not set, we do not create the "Stripe Issuing". In 19.0, `@template` was executed after the post-init hook, and we were preventing the creation of the [journal] at that stage. However, when a new company is created, the template data is automatically loaded for companies with a matching chart of accounts. As a result, the `stripe_issuing_journal` is created, which leads to the error. However, in saas-19.1, due to recent improvements in a [commit], the `@template` will now loads data for companies without post init hook. As a result, the `stripe_issuing_journal` is being created, and we are encountering an error. Solution: - The`Stripe Issuing` journal will no longer be created on installing the module. - For existing databases, we will use the company currency as a fallback value to ensure that a valid currency is applied. [PR]: https://github.com/odoo/enterprise/pull/96271 [journal]: https://github.com/odoo/enterprise/blob/fea009f98885a97439edfea75376b7323c8c9a03/hr_expense_stripe/models/res_company.py#L186-L187 [commit]: https://github.com/odoo/odoo/pull/228950/changes/21fd14ed5e8bdd2cf203d466069437a62a87f2bd sentry-7284934493 Forward-Port-Of: odoo/enterprise#108436
This update corrects a previous error that occurred when the 'Payroll: Update Data' cron job ran, specifically within the Saudi Arabian payroll configuration. The issue stemmed from deleting salary rule categories, which caused a data mismatch during the update process. This fix ensures that the rule category data is updated before the salary rule data, preventing the error and maintaining accurate payroll processing.
Original PR description
Currently, an error occurs when the "Payroll: Update Data" scheduled action is executed. **Steps to Reproduce:** - Install `l10n_sa_hr_payroll` with demo data. - Switch to `Saudi Arabian` company. -…
Currently, an error occurs when the "Payroll: Update Data" scheduled action is executed. **Steps to Reproduce:** - Install `l10n_sa_hr_payroll` with demo data. - Switch to `Saudi Arabian` company. - Go to `Payroll` > `Configuration` > `Salary` > `Rule Categories`. - Delete all records related to the Saudi Arabian company. - Go to `Scheduled Actions` and run `"Payroll: Update Data"`. `ValueError: External ID not found in the system: l10n_sa_hr_payroll.l10n_sa_category_provision` After [this commit], the category_id field becomes non-required, allowing users to delete a rule category record even if it is linked to a salary rule. When updating the data file [1], this causes an error due to the missing rule category [2]. This commit ensures that, when updating the salary rule data, the rule category data is updated beforehand, as shown here [3]. [this commit]: https://github.com/odoo/enterprise/commit/c663fd2a81b7f6b34f8199fdbdc4a75c4f21379e [1]- https://github.com/odoo/enterprise/blob/5ab4cb8bbf8211783a23a4334b633d52633b0324/l10n_sa_hr_payroll/models/hr_payslip.py#L157-L165 [2]: https://github.com/odoo/enterprise/blob/5ab4cb8bbf8211783a23a4334b633d52633b0324/l10n_sa_hr_payroll/data/hr_salary_rule_saudi_data.xml#L249 [3]: https://github.com/odoo/enterprise/blob/5ab4cb8bbf8211783a23a4334b633d52633b0324/l10n_ke_hr_payroll/models/hr_payslip.py#L9-L18 sentry-7349905716
This update fixes an error in the reports generated for Ecuador (l10n_ec_reports_ats) by ensuring the correct 'tipoCliente' value is used for foreign partners. Previously, the system incorrectly identified company types, leading to inaccurate tax reporting. This change aligns with AFIP requirements and ensures compliance.
Original PR description
Since `tipoCliente` is now determined using the computed `is_company` field, the test data must reflect this logic. `partner_ext` represents a foreign partner and is considered a company, therefore its `tipoCliente` should be set to '02'. See: https://github.com/odoo/enterprise/commit/a779badac35cf4a8f483f490e8ae29eb6bf3d2c5 `l10n_ar_edi`: For foreign partners, AFIP requires the CUIT pais based on the partner’s country and document type, not on partner.is_company. In multi-localization databases, is_company may be influenced by local heuristics and lead to picking the wrong foreign tax identifier. Use the identification type instead: VAT documents map to the legal-entity CUIT pais, while non-VAT documents map to the natural-person one. See: https://github.com/odoo/enterprise/pull/86089#discussion_r2128977870 runbot-241126
This update resolves an issue where the topbar menu wasn't correctly updated after a user opened a menu using an AI Agent. The fix ensures the topbar accurately reflects the currently active menu, improving the user experience when interacting with AI-powered features. This enhances usability and consistency.
Original PR description
Purpose: -------- When a menu (view) was opened through an AI Agent, the menu in the topbar was not updated. This commit fixes this behaviour by setting the menu when the menu's action has been loaded Task-6017607 Forward-Port-Of: odoo/enterprise#109929
This update automatically calculates and transmits the required perception commission for Swiss employees through the Swissdec system. This ensures accurate and timely reporting for tax compliance, addressing a previous issue with manual calculations. The change impacts the l10n_ch_hr_payroll module.
Original PR description
task-6050810 Forward-Port-Of: odoo/enterprise#111143
This update fixes an issue where the Gemini AI feature sometimes returned empty responses to users, creating a confusing 'broken' experience. The fix automatically retries the request with a slightly increased processing budget and, after three attempts, gracefully informs the user of the failure. This ensures a more reliable and consistent AI experience.
Original PR description
It often occurs that gemini responses come back empty without anything to show to the users. Specifically, the response object has content but the "parts" are empty - the place were you either get a function call or a message to the user by the LLM. Prior to this commit, when this occured, we didn't perform any explicit handling. We would always just return what the LLM responded with, which when empty would be nothing. UX wise, it would seem like something broke because the user would basically get no reply. In this commit, we add a retry mechanism in `_request_llm_google` of `llm_api_service.py`, where if we get no response, we increase the thinking budget of the next request to 512 and try again. 512 tokens were chosen completely arbitrarily - anecdotally, the model should use around 300 thinking tokens for its tasks so 512 should be enough. After 3 unsuccessful tries, we send a failure response to the user. Task-5959805 Forward-Port-Of: odoo/enterprise#108755
This update fixes a bug where project timesheets didn't accurately reflect changes in manufacturing employees. The fix automatically updates the AAL (analytic accounting line) associated with the work center when an employee is switched, ensuring accurate tracking of labor costs on the project dashboard. This improves the reliability of project cost reporting.
Original PR description
### Steps to reproduce: - Create an MTO product and another Service product that create a project and task - Create a quotation with both products - Create two employees with different hourly cost - Go to Manufacturing order - Configure an employee to manufacture the product at a work station. - Observe the project dashboard - Go back to the MO and change the employee on the work station - Notice the project dashboard Timesheets section doesn't have any change on the amount ### Cause: This is happening because when changing the employee we don't modify anything in the AAL linked to the work station. As we only modify the AAL when the duration change. ### Fix: We call _create_analytic_entry when we change the employee on the work station to change the amount and the employee_id for the AAL. opw-5939321 Forward-Port-Of: odoo/enterprise#111040 Forward-Port-Of: odoo/enterprise#109695
This update resolves an issue preventing invoices with the ICBPER tax code from generating correctly. The fix addresses a technical problem related to how the system handles fixed taxes, ensuring invoices with this tax type now process without errors. This improves the accuracy of invoice generation for Peruvian businesses.
Original PR description
**Steps to reproduce:** 1. Install module `l10n_pe_edi`. 2. Switch company to PE. 3. Create a tax: - Name: ICBPER - Amount type: Fixed - Code: ICBPER - Amount: 0.5(e.g.) - Set the tax group to ICBPER…
**Steps to reproduce:**
1. Install module `l10n_pe_edi`.
2. Switch company to PE.
3. Create a tax:
- Name: ICBPER
- Amount type: Fixed
- Code: ICBPER
- Amount: 0.5(e.g.)
- Set the tax group to ICBPER (In Advance Option)
4. Create a invoice and add a product with ICBPER tax.
5. Post the invoice and click "Process Now" (at header).
**Issue:**
Processing the invoice raises:
AttributeError: 'dict' object has no attribute '_get_downpayment_lines'
**Cause:**
When `fixed_taxes_as_allowance_charges` is True, `_setup_base_lines()` calls `_turn_emptying_taxes_as_new_base_lines()`, which splits fixed taxes (e.g., ICBPER) into separate base lines.
During this process, `base_line['record']` is no longer the original `account.move.line` record. Instead, it becomes a dictionary containing record under `base_line['record']['record']`.
- With the flag enabled: `base_line['record']` -> dict `line._get_downpayment_lines()` -> AttributeError
- With the flag disabled: `base_line['record']` -> `account.move.line``line._get_downpayment_lines()` -> works correctly
The Peru EDI implementation directly accesses `base_line['record']` expecting an `account.move.line`. The the nested dict structure causes the crash during file generation.
**Solution:**
Override `_add_invoice_config_vals()` to explicitly set `fixed_taxes_as_allowance_charges = False`
- Add test to ensure invoices with ICBPER fixed taxes generate XML without error
**opw-5809939**
Forward-Port-Of: odoo/enterprise#108638This update resolves issues with overtime calculations related to employee timezones. Previously, the system incorrectly handled overlapping attendances and failed to properly delete outdated overtime lines, leading to inaccurate reporting. This fix ensures accurate overtime tracking regardless of employee timezone settings.
Original PR description
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a…
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a period, then create two consecutive midnight-to-midnight attendances in the employee's local timezone. Creating the second attendance crashes with: "ValueError: Expected singleton: hr.attendance.overtime.line(...)". Steps to reproduce (stale overtime lines): With the same setup, delete the attendance after it generated overtime lines. The overtime lines remain in the database instead of being removed. The singleton crash occurred because `end_of_day` in `_get_overtime_intervals` was computed as a naive datetime, implicitly treated as UTC. For UTC+ timezones, the actual local end of day is earlier than UTC midnight. As a result, overtime intervals were computed with a stop time extending past the real local midnight into UTC time. When consecutive attendances were processed together, these extended intervals overlapped. The `Intervals` class (`keep_distinct=True`) merges overlapping intervals into a single entry with a multi-record recordset as payload. The subsequent `overtime.rule_ids.work_entry_type_id` and `overtime.status` calls expected a singleton but received a multi-record set, causing the crash. The same multi-record issue also affected the iteration in `_set_real_overtime_intervals` and the overtime work entry loop in `_get_attendance_intervals`. The stale overtime lines issue occurred because `_get_overtimes_to_update_domain` (hr_attendance) built its search date range from raw UTC `.date()` values instead of the employee's local timezone. For UTC+ employees whose attendance spans local midnight, the overtime line is dated in the next local calendar day. Since the domain was derived from UTC dates, that next local day fell outside the search range, so the overtime line was never found and deleted when the attendance was removed. Solution: - In `_get_overtime_intervals`, localize `end_of_day` to the employee's timezone before converting to UTC, so overtime intervals are correctly bounded by the local end of day. - In `_set_real_overtime_intervals` and the overtime loop in `_get_attendance_intervals`, iterate over individual records from potentially multi-record `Intervals` payloads to avoid singleton errors. - In `_get_overtimes_to_update_domain` (hr_attendance), localize check_in/check_out to the employee's timezone before computing the date range so overtime lines for dates that only exist in local time are correctly included in the delete-and-recreate cycle. opw-5931665 Forward-Port-Of: odoo/enterprise#109419
This update ensures that manufacturing orders are created separately for MTO products that share components. Previously, only one MO was created, leading to tracking issues. Now, each product with shared components will have its own distinct manufacturing order, improving inventory accuracy and traceability.
Original PR description
Currently, when a user creates a Sale Order for MTO products that share the same component (which itself has a BOM), the system does not create a separate child MO for each manufacturing order. ##…
Currently, when a user creates a Sale Order for MTO products that share the same component (which itself has a BOM), the system does not create a separate child MO for each manufacturing order. ## Steps to produce: - Install Sales and Manufacturing - Go to Settings and turn on Replenish on Order (MTO). - Create products 'Wooden Arrow' and 'Wooden Rod' with a BOM that includes: - 'Stick', which itself has a BOM with 'Raw stick'. - On each product page, go to Inventory and enable the MTO route, except for 'Raw Stick' . - Create a Sale Order for Wooden Arrow and Wooden Rod for Customer 'Administrator'. - Confirm the Sale Order. - Go to Manufacturing > Open and check both Manufacturing Orders. ## Observed Behavior: Currently, the manufacturing order for 'Wooden Arrow' has a child MO, but the order for 'Wooden Rod' does not. The child MO under 'Wooden Arrow' produces two sticks at once. However, each manufacturing order should have its own separate child MO so that every item is produced and tracked individually. ## Root cause: The issue happens because when a Sale Order is confirmed, [_run_manufacture](https://github.com/odoo/odoo/blob/7c7c6663e28974834d1569b27605f6ce400c7b16/addons/mrp/models/stock_rule.py#L81-L120) is called. This method creates a new MO or updates an existing one based on the domain returned by `_make_mo_get_domain` [1]. For 'Wooden Arrow' and 'Wooden Rod; new MOs are created because no existing MO matches their BOM ID, product ID, or reference. They are added to `new_productions_values_by_company` [2], which is then used to create the MOs [3]. When `_run_manufacture` runs for 'Stick', it is triggered twice since both MOs require it as a component. The first time, no MO matches the domain, so a new one is created. The second time, the domain matches the existing MO (same BOM ID and product ID), so that MO is updated instead [4]. Because of this, `new_productions_values_by_company` is not filled again, and no second child MO is created. [1]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L146-L165 [2]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L98-L103 [3]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L113-L115 [4]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/mrp/models/stock_rule.py#L105-L110 ## Solution: To resolve this issue, the domain has been tightened to include the parent production group ID. Since the parent MO’s group ID is passed through the procurement variable when `_run_manufacture` is executed for its component products, this group ID can be used to ensure the correct MO is matched. **Why modify the existing test case?:** With this change, in the `test_sale_mrp_pickings` test case, a new child MO for 'Stick' is created under the MO for 'Arrow' instead of modifying another parent MO for 'Stick'. The test case has been updated accordingly. (Confirmed the new behavior with CRL and TAGO) opw-5480133 Forward-Port-Of: odoo/odoo#248229
This update fixes an issue where consolidated POS invoices were incorrectly showing a zero payable amount due to pre-payment mapping. MyInvois now requires invoices to accurately reflect the total amount, regardless of prior payments. This change ensures the payable amount aligns with MyInvois API requirements, resolving a compatibility problem.
Original PR description
For POS consolidated invoices, the PrePayment Amount was mapped to the payment linked to the document. This incorrectly decreased the Total Amount Payable to 0, since POS orders are already paid at the counter. MyInvois tax officer and helpdesk requires that the Total Amount Payable (cbc:PayableAmount) to reflect the total amount of the issued e-document , regardless of prior payments. This commit forces the PaidAmount to 0 for consolidated documents, ensuring the PayableAmount correctly matches the TaxInclusiveAmount as expected by the MyInvois API. task-[6021698](https://www.odoo.com/odoo/all-tasks/6021698) Forward-Port-Of: odoo/odoo#254183 Forward-Port-Of: odoo/odoo#253499
This update optimizes how Odoo handles large sales orders, significantly speeding up the rendering process. Previously, a slow process was triggered when processing many order lines, leading to UI delays. Now, the system pre-computes parent-child relationships, resulting in a much smoother and faster experience for users.
Original PR description
This commit resolves a performance bottleneck that occurred when handling very large sale orders (e.g., ~200 order lines). Previously, the util function `getParentSectionRecord` determined the parent…
This commit resolves a performance bottleneck that occurred when handling very large sale orders (e.g., ~200 order lines). Previously, the util function `getParentSectionRecord` determined the parent (sub)section of an order line by iterating over all preceding order lines. Since this logic was executed for each order line, the overall complexity became O(n²). Moreover, this function was invoked inside the `shouldCollapse` method, which is used in multiple UI flows during rendering. As a result, large sale orders could cause noticeable UI slowdowns and block the main JavaScript thread. To address this, we now build a parent–child section mapping once per render in O(n) time. Subsequent lookups simply read from this mapping instead of recomputing the parent by scanning previous lines. This significantly reduces the computational cost and prevents UI blocking when working with large orders, leading to a much smoother rendering experience. opw-5865167 Benchmark: | No. records | Before | After | |----------------|---------------|--------------| | 150 | 1300ms | ~850ms | | Before | After | |---------------|--------------| | <img width="287" height="284" alt="image" src="https://github.com/user-attachments/assets/dd73ab18-3c53-4958-99b7-083dd5cd9e64" /> | <img width="311" height="277" alt="image" src="https://github.com/user-attachments/assets/b6e90fa3-85eb-4d72-b616-28aff9a938e8" />| --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252991
This update resolves an issue where project sharing visibility was incorrectly changing after sharing with portal users. The change ensures that projects shared with 'Invited internal users and portal users' retain their intended visibility settings, preventing unintended changes to user access. This improves the reliability of project sharing workflows.
Original PR description
Steps to reproduce: - Create/open any project - Set visibility to `Invited internal users and portal users`. - Share project with a portal user - Visibility changes to `All internal users and invited portal users`. Cause: - Previously, this behavior was implemented specifically for sharing the project from the cog menu. However, the `Share Project` option has now been removed from the cog menu. - After introducing the new `invited_users` visibility option, the existing share logic was not updated to support this new value; as a result, the project's existing visibility is unintentionally overwritten. Solution: - Remove the hardcoded update of `privacy_visibility` in the `action_send_mail` method. task-5924243 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#248235
This update resolves an issue preventing users from adding a partner's bank account to the 'Recipient Bank' field when creating a credit note. Previously, this field only showed company accounts, blocking credit note processing. Now, the field correctly prefilters bank accounts based on the expected recipient, enabling proper credit note creation.
Original PR description
Description of the issue this commit addresses: The Recipient Bank field in the Other Info tab of the Account Move form view refilters accounts to only show you company's ones. This is expected for invoices but is blocking when doing a credit note. You can't find a partner's bank account to fill that field. --- Steps to reproduce: 1. Install account. 2. Create an Invoice to a partner which has a bank account setup. 3. Create a Credit Note for that Invoice. 4. In the "Other Info" tab, remove the partner's bank account. 5. Try to search for his bank account to add it back. It won't show up. --- Desired behavior after this commit is merged: The Recipient Bank field prefilters bank accounts based on who is expected to be the recipient of the move. --- task-5976951 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254850 Forward-Port-Of: odoo/odoo#252961
This update fixes issues with the XML invoices generated for Spanish VAT (EDI) reporting. Specifically, it now correctly calculates and formats tax outputs per tax type instead of per line item, and enables rounding for tax data aggregation. This ensures accurate VAT reporting and compliance.
Original PR description
- Adjusting invoice-level `<TaxesOutputs>` nodes to be generated per tax rather than per line - Enabling rounding for invoice-level tax data aggregation - Adding a second rounding test derived from bug ticket task-6009108 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253305
This update corrects a problem where invoices using fixed taxes for 'consigne/vidange' were failing Peppol validation. The fix adjusts how tax exemptions are handled during invoice generation, ensuring compliance with Peppol standards and allowing these invoices to be successfully processed.
Original PR description
**PROBLEM** Here is the client use case: The client uses fixed tax to do 'vidange/consignage'. When selling a product with a 'consigne/vidange', they add a fixed tax which amount correspond to the…
**PROBLEM** Here is the client use case: The client uses fixed tax to do 'vidange/consignage'. When selling a product with a 'consigne/vidange', they add a fixed tax which amount correspond to the 'consigne/vidange'. When returning the 'consigne', you would create an invoice line, with a product with a price of 0, negative quantity,a 0% tax and the fixed tax for the 'consigne'. When an invoice contains such lines, it fails peppol validations. **STEP TO REPRODUCE** 1. Create a fixed tax used for 'vidange/consigne'. 2. Create an invoice, with a line with unit price of 0, negative quantity, a 0% tax and the fixed tax for the 'consigne'. 3. Send the invoice using peppol, use a validator to validate the xml and notice you get the following errors: [BR-E-01] [BR-E-08]. **CAUSE** Fixed tax (like the one used for vidange) are aggregated in new invoice lines by the function `_ubl_turn_emptying_taxes_as_new_base_lines()`. Let say we have the following invoice: line 1: qty=2, unit_price=3, taxes: 21% & vidange(fixed tax of 1). line 2: qty=-1, unit_price=0, taxes: 0% & vidange. After calling `_ubl_turn_emptying_taxes_as_new_base_lines()`, we got: line 1: qty=2, unit_price=3, taxes: 21%. line 2: qty=-1, unit_price=0, taxes: 0%. line 3: qty=1, unit_price=1(amount of the fixed tax), taxes:None. When generating the VAT breakdown, we have 2 line will end up being tax exempted (line 2 and 3). Because the `tax_exemption_reason` differs, they will not be merged in the same entry in the breakdown, which break the constraint of peppol saying we can only have one VAT breakdown with code 'Exempt from tax'. Line 2 reason comes from: https://github.com/odoo-dev/odoo/blob/de22093ee225df499b2de80e1f07dd281ac686bc/addons/account_edi_ubl_cii/models/account_edi_common.py#L271-L274 opw-5912986 Forward-Port-Of: odoo/odoo#254875 Forward-Port-Of: odoo/odoo#250413
This update fixes a bug where customers could unintentionally modify global discount lines within optional sections of sales orders. The change prevents customers from editing these discount lines, ensuring accurate order pricing and preventing potential revenue discrepancies. This improves order accuracy and reduces the risk of errors.
Original PR description
Issue: --- Due to this issue global discount line can be edited by customer. #### Steps to reproduce: 1- Create a SO with SOLs and add a optional section. 2- Add a global discount under optional section. 3- Preview the SO. The quantity of discount can be edited. Cause and Fix: --- In `_can_be_edited_on_portal` we are not excluding the global discount line from being editable. We could fix that by excluding line with company discount product from being editable. opw-6045297 Forward-Port-Of: odoo/odoo#254870
This update ensures payment methods created within a company branch can be consistently used across all company branches, resolving a previous validation error. The fix adds a necessary constraint to the payment method model, aligning with existing company checks and preventing inconsistencies in the point-of-sale system. This improves data integrity and user experience.
Original PR description
Steps to reproduce: ------------------- * Let's say you're on company A, create a pos payment method * Don't assign a pos yet * Create a branch company sub_A * Switch to that branch company * Create…
Steps to reproduce: ------------------- * Let's say you're on company A, create a pos payment method * Don't assign a pos yet * Create a branch company sub_A * Switch to that branch company * Create a pos * Now switch to company A but also select sub_A * In the config of the pos from sub_A, try to add the new payment method and save > Validation error -> Normal * Now instead go to the payment method form * In the point of sales select the pos sub_A * Save > No error * Try opening the pos sub_A > Validation error, same as the first one -> Normal Why the fix: ------------ We already have a contraint on the pos config model checking that the companies match. https://github.com/odoo/odoo/blob/88df50bc96448dfaff28bd37e970ffd18bf8d554/addons/point_of_sale/models/pos_config.py#L469-L473 However when writing on the model pos payment there is no constraint and the ORM currently does not trigger constraints on comodel of the field we're modifying so we need to add this constraint on the pos payment method model as well opw-6000206 Forward-Port-Of: odoo/odoo#253858
This fix ensures that product order lines in the Point of Sale (POS) system accurately reflect all assigned attributes, regardless of whether the product is selected or scanned. Previously, the system displayed inconsistent information, leading to inaccurate order details. This update corrects this behavior, improving the reliability of POS transactions.
Original PR description
Currently, when a product has more attribute values then variant values (some attribue can have only one option), the pos behaves differently depending if you select the product or scan it. Steps to reproduce: ------------------- * Modify the acoustic bloc screen "Attributes & Variants" tab * Have one attribute line Color, only White as values * Have one attribute line Size, S and M as values * Go to the variants, select the one corresponding to the Size S > Observe it also has the attribute White * Set a barcode on this variant * Open shop * Select Acoustic Bloc Screens, select Size S, confirm * Now scan the barcode > Observation: 2 Different pos order lines on the order, the first shows S, White as attributes, the second one only shows S. Why the fix: ------------ We need to use all attribute values, not only the variant values. opw-5932560 Forward-Port-Of: odoo/odoo#252233
This update fixes an issue where the VAT Return (CZ) report was incorrectly displaying negative amounts when using VAT 24 or VAT 23 tax grids on invoices with credit amounts. The change ensures the report accurately reflects VAT amounts, improving the reliability of Czech Republic tax reporting within Odoo.
Original PR description
With l10n_cz company: 1. Create some invoices using the VAT 24 or VAT 23 tax grid on an invoice line containing an amount in credit. 2. Go to the VAT Return (CZ) report 3. The amount shown will be negative instead of positive, which goes against what the report should show. Missed by 17a6117ed88c29b5bc4db0c872bcdbc109a7d98b opw-5978183 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#252243
This update resolves issues with overtime calculations related to timezone differences, specifically impacting how attendances are processed in UTC+ timezones. The fix ensures accurate overtime intervals are generated and prevents crashes or stale overtime records, improving the reliability of employee time tracking.
Original PR description
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a…
Steps to reproduce (singleton crash): Create an employee in a UTC+ timezone (e.g. Asia/Shanghai or Australia/Adelaide) with an overtime ruleset containing a paid rule. Generate work entries for a period, then create two consecutive midnight-to-midnight attendances in the employee's local timezone. Creating the second attendance crashes with: "ValueError: Expected singleton: hr.attendance.overtime.line(...)". Steps to reproduce (stale overtime lines): With the same setup, delete the attendance after it generated overtime lines. The overtime lines remain in the database instead of being removed. The singleton crash occurred because `end_of_day` in `_get_overtime_intervals` was computed as a naive datetime, implicitly treated as UTC. For UTC+ timezones, the actual local end of day is earlier than UTC midnight. As a result, overtime intervals were computed with a stop time extending past the real local midnight into UTC time. When consecutive attendances were processed together, these extended intervals overlapped. The `Intervals` class (`keep_distinct=True`) merges overlapping intervals into a single entry with a multi-record recordset as payload. The subsequent `overtime.rule_ids.work_entry_type_id` and `overtime.status` calls expected a singleton but received a multi-record set, causing the crash. The same multi-record issue also affected the iteration in `_set_real_overtime_intervals` and the overtime work entry loop in `_get_attendance_intervals`. The stale overtime lines issue occurred because `_get_overtimes_to_update_domain` built its search date range from raw UTC `.date()` values instead of the employee's local timezone. For UTC+ employees whose attendance spans local midnight, the overtime line is dated in the next local calendar day. Since the domain was derived from UTC dates, that next local day fell outside the search range, so the overtime line was never found and deleted when the attendance was removed. Additionally, `_get_localized_times` called `.astimezone()` on naive UTC datetimes without first localizing them, producing incorrect local times for the same reason. Solution: - In `_get_overtimes_to_update_domain`, localize check_in/check_out to the employee's timezone before computing the overtime search date range (with a ±1 day buffer) so overtime lines for dates that only exist in local time are correctly included in the delete-and-recreate cycle. - Fix `_get_localized_times` to call `utc.localize()` on naive UTC datetimes before converting to the employee's timezone. opw-5931665 Forward-Port-Of: odoo/odoo#251812
This update corrects a validation error that occurred when generating invoices in the Belgian accounting module (l10n_be) using Peppol. The fix addresses a rounding discrepancy that caused the invoice XML to fail validation, ensuring compliance with VAT regulations. It achieves this by correctly handling decimal rounding differences.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_be - Switch to a Belgian company (e.g. BE Company CoA) - In Accounting settings: * activate Peppol * set "Rounding Method" to "Round Globally" -…
**Steps to reproduce:**
- Install Accounting and l10n_be
- Switch to a Belgian company (e.g. BE Company CoA)
- In Accounting settings:
* activate Peppol
* set "Rounding Method" to "Round Globally"
- Create an invoice:
* Customer: [a Belgian customer with a VAT]
* Invoice Lines:
| Label | Quantity | Price | Taxes |
| ------- | ---------- | ------- | ------- |
| Line 1 | 1.0 | 90.30 | 0% |
| Line 2 | 0.45 | 2.54 | 6% |
| Line 3 | 0.28 | 6.87 | 6% |
- Confirm the invoice
- Send the invoice to Peppol
**Issue:**
The generated XML has a line with `<cbc:LineExtensionAmount>` set to 90.31, `<cbc:InvoicedQuantity>` set to 1.0 and `<cbc:PriceAmount>` set to 90.30, which fails the validation with the following error:
`[BR-E-08]-In a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Exempt from VAT" the VAT category taxable amount (BT-116) shall equal the sum of Invoice line net amounts (BT-131) minus the sum of Document level allowance amounts (BT-92) plus the sum of Document level charge amounts (BT-99) where the VAT category codes (BT-151, BT-95, BT-102) are "Exempt from VAT".`
**Cause:**
The use of decimal number in quantity generates a 0.01 rounding difference in the base amounts.
The extra cent is dispatched in one of the `<cbc:LineExtensionAmount>` node.
**Solution:**
There is no easy solution to handle these rounding cases. The solution used in this fix is to handle the extra cents as if they are cash rounding amount and declare them in `<cbc:PayableRoundingAmount>` node.
opw-5933545
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#255095
Forward-Port-Of: odoo/odoo#253625This update optimizes a key stock query that previously performed very slowly due to complex string comparisons. The change replaces these comparisons with a more efficient method of checking location ancestry using integer IDs, dramatically reducing query execution times, especially when dealing with large lists of locations. This improves overall system responsiveness and stability.
Original PR description
### Description of the issue/feature this PR addresses: Some stock queries determine whether a location belongs to the subtree of a set of locations by checking the parent_path prefix against…
### Description of the issue/feature this PR addresses:
Some stock queries determine whether a location belongs to the subtree of a set of locations by checking the parent_path prefix against candidate parent locations. This is done using a correlated EXISTS subquery with a LIKE parent.parent_path || '%' condition.
When the list of candidate locations becomes large (for example tens or hundreds of thousands of ids), this approach causes extremely poor performance because the database must repeatedly compare hierarchical path strings for every candidate row.
This PR improves the performance of this ancestry check by replacing the string prefix comparison with a direct check on the ancestor ids contained in parent_path.
### Current behavior before PR:
The query determines whether a location belongs to the subtree of one of the provided locations using:
location.parent_path LIKE parent.parent_path || '%'
For each row, PostgreSQL must evaluate a correlated subquery against all candidate parent locations. Because this relies on string prefix comparisons on parent_path, when the location list is large, this results in extremely slow queries.
### Desired behavior after PR is merged:
Instead of performing string prefix comparisons, the query extracts the ancestor ids directly from parent_path.
The path is:
1. Trimmed to remove leading and trailing /
2. Split into an array of ancestor ids
3. Expanded using unnest
4. Checked for intersection with the provided location ids
This converts the ancestry check from repeated string comparisons into a simple integer membership check.
### Benchmarks
Comparing performance of old subquery:
```
SELECT stock_location_inner.id
FROM stock_location AS stock_location_inner
WHERE EXISTS (
SELECT 1
FROM stock_location parent
WHERE parent.id IN (long list)
AND stock_location_inner.parent_path LIKE parent.parent_path || '%%'
);
```
to new one:
```
SELECT stock_location_inner.id
FROM stock_location AS stock_location_inner
WHERE EXISTS (
SELECT 1
FROM unnest(
string_to_array(trim(both '/' FROM stock_location_inner.parent_path), '/')::int[]
) AS path_id(id)
WHERE path_id.id IN (long list)
);
```
Depending on the number of elements in 'long list'
| # of elements | Before | After |
| --- |---|---|
| 130,000 | 21min | 0.8sec |
| 10,000 | 95sec | 0.5sec |
| 1,000 | 10.5sec | 0.5sec |
In practice, on the reference ticket this causes the "Validate" button on a stock picking to go from timing out to taking 8 seconds.
### Reference
opw-5932436
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#2542455 changes
Resolved issues and error corrections
This update corrects a bug where payslip dates were incorrectly using the employee's start date instead of their first contract date within the company. The system now uses the employee's initial contract date, ensuring accurate payroll reporting and compliance. This change was implemented as a fix to improve data consistency.
Original PR description
…irst contract date in payslips - `first_contract_in_company` is now a computed field instead of being manually populated in the departure notice wizard. - `first_contract_in_company` is now used for the first contract date in payslip reports instead of using the current version's start date. - in departure notice wizard fixed how `first_contract` is calculated by using the refactored `_get_first_version()` function. - removed manual update of `first_contract_in_company` in the departure wizard as it is now handled by the compute. Task: 5368029
This update automatically calculates and transmits the required perception commission for Swiss employees' payrolls. This ensures accurate tax reporting to the Swiss tax authorities, addressing a previous reporting issue. The change improves compliance and reduces the risk of errors related to commission calculations.
Original PR description
Forward-Port-Of: odoo/enterprise#111143
This update fixes an issue where the SDWorx payroll report didn't account for public holidays. The change ensures that employee attendance is accurately calculated, reflecting actual working days as defined by public holidays. This improves the reliability of payroll reporting.
Original PR description
### Steps to reproduce: - Setup a public holiday in a month January for example - Add a leave for an employee for the whole Month of January - Export the SDworx report - Notice for the day of the public holiday, it is shown as a normal attendance ### Cause: When checking leaves for the SDWorx report we only check hr.leave we don't check resource.calendar.leaves ### Fix: We take resource.calendar.leaves now into account to make sure we add public holidays to the report when exporting it opw-5500070 Forward-Port-Of: odoo/enterprise#106065
This update fixes an issue where repositioning a signature within the PDF viewer caused inconsistent resizing behavior due to multiple event listeners. The change ensures only one resize listener is attached, resulting in a more reliable and predictable resizing experience for users. This improves the overall usability of the signature feature.
Original PR description
Previously, repositioning a sign item inside the PDF iframe would attach multiple resize event listeners. This led to inconsistent and unintuitive resizing behavior. This commit ensures that only a single resize listener is registered per item, avoiding duplicated handlers and restoring stable interaction. task-6048759 Forward-Port-Of: odoo/enterprise#111520 Forward-Port-Of: odoo/enterprise#111146
This update fixes an issue where multi-select rectangles on scaled PDF signature pages were inaccurately drawn, leading to incorrect selections. Additionally, the fix addresses a potential error when dropping elements and ensures helper lines align properly during dragging. This enhances the reliability and usability of the signature process.
Original PR description
When drawing the multi-select rectangle on scaled PDF pages, the rectangle corner was not properly synchronized with the mouse pointer, leading to inaccurate selection. Additional fixes: - An uncaught error could be triggered when dropping elements on the page. - Helper lines during dragging were not accurately aligned around sign items. task-6049004 Forward-Port-Of: odoo/enterprise#111156
9 changes
Resolved issues and error corrections
This update optimizes how Odoo loads its registry, significantly reducing the time it takes to start up, especially for customers with large addon installations. By avoiding unnecessary file system scans, the change dramatically improves performance and responsiveness, leading to faster request processing.
Original PR description
In `ThreadedServer,` the http daemon will create threads to handle incoming requests. The creation of these threads doesn't wait until the registry is loaded because the request could be serving…
In `ThreadedServer,` the http daemon will create threads to handle incoming requests. The creation of these threads doesn't wait until the registry is loaded because the request could be serving static files. In the WSGI application entry point `__call__`, the threads will be going into `self.get_static_file` and up until this point, there's no locking whatsoever on these threads. Inside `get_static_file`, the `self.statics` lazy_property is evaluated which will walk the addons path. Before this PR, the order of the conditions in the or statement will always evaluate the lazy property regardless of the other parts of the condition. This means that every single request that comes in will do an unnecessary `os.listdir` on all addons paths. For customers with a very large and deeply nested addons path like in opw-5877522 (they had over 93K dirs), this is a tremendous load on the system when there are multiple threads doing that due to the amount of syscalls involved for no reason whatsoever. This is especially worse on SH because disks are not local, so an individual syscall is more expensive. This is slowing down all requests as well as the registry loading time which is a prerequisite for any non-static request. This PR simply reorders this check to only evaluate the self.statics property if all other parts of the condition are False. This means it'll only have to do this expensive `os.list` for a fewer number of requests which are much more unlikely to coincide at the startup of a worker. On top of that it's a better optimization to avoid doing this expensive check for every request. Benchmarks |No. files in addons path| No. concurrent threads | Registry loading time Before PR | Registry loading time After PR | |--------|--------|--------|--------| | 93447 | 5 | 53.23 s | 4 s | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254660
This update automatically calculates and transmits the necessary commission information for Swiss payroll declarations (ELM). Previously, this calculation was manual, introducing potential errors and delays. This change ensures accurate and timely reporting to Swiss tax authorities, streamlining the payroll process.
Original PR description
Forward-Port-Of: odoo/enterprise#111143
This update corrects a validation issue in the ZATCA XML generation for Saudi Arabia companies. Previously, the system didn't include cash rounding amounts in the payable calculation, leading to validation errors. This change ensures accurate payable amount calculations for invoice validation, aligning with ZATCA requirements.
Original PR description
Currently the generated ZATCA XML is not accounting for invoice cash rounding, leading to an invoice validation issue due to a mismatch in the calculation of PayableAmount. Steps to reproduce: - Have a SA Company setup - Create a [cash rounding] with strategy 'Add invoice line' and rounding 1.00 (UP) - Create an invoice for 99.55 + 15% Tax - Set Cash Rounding Method to [cash rounding] - Confirm and send xml for validation Issue: Validation will issue the following warning `[202] BR-CO-16 : Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Pre-Paid amount (BT-113) + Rounding amount (BT-114).` Analysis: The ZATCA implementation was calculating the payable amount strictly as (TaxInclusiveAmount - PrepaidAmount). This change ensures the rounding amount is fetched and added to the total payable calculation opw-5939550 Forward-Port-Of: odoo/odoo#254450 Forward-Port-Of: odoo/odoo#253555
This update fixes a bug where users could confirm popups with empty input fields, such as gift card codes. Now, the confirmation button is disabled if the input is blank or contains only spaces, ensuring data integrity and preventing incorrect transactions. This impacts key features like adding floors and generating gift cards.
Original PR description
*= point_of_sale, pos_loyalty, pos_restaurant Before this commit: =================== - User was able to confirm `TextInputPopup` with an empty input value. Affected functionalities: - Add New Floor - Rename Floor / Table - Enter Code (Gift card or Discount code) - Generate a Gift Card After this commit: ================== - The confirm button will be disabled if the input value is empty or has only spaces so that an empty string will not be accepted. Task-6019160 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254994 Forward-Port-Of: odoo/odoo#253307
This update fixes an issue where multi-select rectangles on scaled PDF signature pages were inaccurately drawn, leading to incorrect selections. Additionally, the update resolves a potential error when dropping elements and ensures helper lines align correctly during dragging. This improves the overall usability and reliability of the signature process.
Original PR description
When drawing the multi-select rectangle on scaled PDF pages, the rectangle corner was not properly synchronized with the mouse pointer, leading to inaccurate selection. Additional fixes: - An uncaught error could be triggered when dropping elements on the page. - Helper lines during dragging were not accurately aligned around sign items. task-6049004
This update fixes an issue where repositioning PDF sign items caused inconsistent resizing behavior due to multiple event listeners being attached. The change ensures only one resize listener is registered, resulting in a more stable and predictable user experience when working with PDF signatures. This improves the reliability of the sign request process.
Original PR description
Previously, repositioning a sign item inside the PDF iframe would attach multiple resize event listeners. This led to inconsistent and unintuitive resizing behavior. This commit ensures that only a single resize listener is registered per item, avoiding duplicated handlers and restoring stable interaction. task-6048759 Forward-Port-Of: odoo/enterprise#111146
This update corrects a bug where a down payment line was incorrectly added twice to POS order settlements when automatic invoicing was enabled. The fix ensures that only the initial down payment line is processed, preventing data duplication and ensuring accurate order totals. This improves the reliability of POS transactions.
Original PR description
Case 1: --- **Steps to produce:** - Install `pos_sale` module. - Enable `Automatic Invoice` in settings - Create a new SO with product price 1000. - In `Other Info`, set `Online Payment` to 30%. -…
Case 1: --- **Steps to produce:** - Install `pos_sale` module. - Enable `Automatic Invoice` in settings - Create a new SO with product price 1000. - In `Other Info`, set `Online Payment` to 30%. - Preview > make payment > down payment of 300 is created in SO. - In POS, open Furniture Shop register > Actions > Quotation/Order > select the SO > settle order. **Issue:** - The down payment line is added twice in the POS order. **Root cause:** - At [1], `sale_order.amount_paid` = 300, so `addDownPaymentProductOrderlineToOrder` adds the line in order. - At [2], the down payment line from the SO is added again. - Here, when `Automatic invoice` is on and we make the online payment then `amount_paid` is updated and the downpayment invoice is also created. - So, we have also downpayment line in sale order also. **Solution:** - Ensure that if a downpayment line has already been added to the POS order, the first downpayment line matching `amount_paid` is skipped. [1]: https://github.com/odoo/odoo/blob/54a62bdbe927108a7f85374db26787f8ba45f6ac/addons/pos_sale/static/src/overrides/models/pos_store.js#L88-L93 [2]: https://github.com/odoo/odoo/blob/54a62bdbe927108a7f85374db26787f8ba45f6ac/addons/pos_sale/static/src/overrides/models/pos_store.js#L109-L111 Before: <img width="484" height="279" alt="image" src="https://github.com/user-attachments/assets/c803c9bd-0751-4a90-81f4-8fb3da3b393e" /> After: <img width="490" height="235" alt="image" src="https://github.com/user-attachments/assets/2ec4ac43-1db3-4c2e-bfcf-8c52a4830dac" /> Case 2: --- **Steps to produce:** - Install `pos_sale` module. - Enable `Automatic Invoice` in settings - Create a new SO with product price 1000. - In `Other Info`, set `Online Payment` to 30%. - Preview > make payment. **Issue:** -The computed value of amount_unpaid is 400, whereas it should be 700. **Root cause:** - When Automatic Invoice is enabled and an online payment is made, the invoice is automatically created and amount_paid is also updated. - At [3], the logic subtracts both the total invoice amount and amount_paid from the actual total, which results in an incorrect calculation. **Solution:** - When an online payment is made, a transaction is created and linked to an invoice. - While computing the total invoice amount, if the transaction’s invoice ID is encountered again, it should be skipped to avoid double-counting. [3]: https://github.com/odoo/odoo/blob/75f6be6744006ed1a3c0857881822723f90f5d4a/addons/pos_sale/models/sale_order.py#L46-L51 opw-5415404 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254964 Forward-Port-Of: odoo/odoo#242026
This update fixes an issue in our tax reporting calculations, specifically when using 'trimester' tax periods. The previous calculation incorrectly identified date boundaries, leading to inaccurate report values. This change ensures correct reporting for carryover tax scenarios, improving data accuracy for financial reporting.
Original PR description
To reproduce the issue: - Setup tax periodicity to "trimester" - Create a report evaluating something with previous_tax_period date_scope (real cases tend to do that for carryover ; see monthly…
To reproduce the issue: - Setup tax periodicity to "trimester" - Create a report evaluating something with previous_tax_period date_scope (real cases tend to do that for carryover ; see monthly Italian tax report for an example) - Create the appropriate data so that in the current trimester, the report line evaluates to 42, and to 1 in the previous trimester - Open the report for the second month of the trimester => The line has value 42, while it should have 1. This happens because the date bounds for previous_tax_period were computed too naively, considering the date_from was always the first day of the tax period. The first day of the second month of the trimester, it's not the case, and we return the period boundaries of the day before that day. That day is the last day of the first month of the trimester, but belongs to the same trimester, so it's the same tax period. Therefore, we display the value of the current tax period, which is wrong. Forward-Port-Of: odoo/enterprise#111330 Forward-Port-Of: odoo/enterprise#110504
This update ensures the SDWorx payroll report accurately reflects employee attendance by now considering public holidays. Previously, the report didn't account for resource calendar leaves, leading to incorrect attendance calculations. This fix improves the accuracy of payroll reporting for Belgium.
Original PR description
### Steps to reproduce: - Setup a public holiday in a month January for example - Add a leave for an employee for the whole Month of January - Export the SDworx report - Notice for the day of the public holiday, it is shown as a normal attendance ### Cause: When checking leaves for the SDWorx report we only check hr.leave we don't check resource.calendar.leaves ### Fix: We take resource.calendar.leaves now into account to make sure we add public holidays to the report when exporting it opw-5500070 Forward-Port-Of: odoo/enterprise#106065
4 changes
Resolved issues and error corrections
This update resolves an issue where the XML generated for Swiss payments (iso20022_ch) was using an outdated payment schema. The fix ensures the XML adheres to current Swiss banking standards, improving payment processing accuracy and compliance. It also includes enhancements for validator schema and QR-IBAN support.
Original PR description
**PROBLEM** According to documentation (https://www.six-group.com/dam/download/banking-services/standardization/sps/ig-credit-transfer-sps-2025-en.pdf) PstlAdr must be structured. This isn't the case when generating a xml for the payment method iso20022_ch. **STEP TO REPRODUCE** 1. install l10n_ch and account_iso20022. 2. Create a swiss contact with a full address. And activate payment on the bank account of this contact. 3. Select the Company CH, and set a bank account in the bank journal configuration. 4. Create a vendor payment to the swiss contact. 5. Create a batch payment with it, and validate to get the xml. 6. Open the xml, and notice the PstlAdr isn't structured. Ticket [link](https://www.odoo.com/odoo/project.task/5880247) opw-5880247 Forward-Port-Of: odoo/enterprise#107025
This update automatically calculates and transmits the required commission payments (ELM) for Swiss payroll, streamlining the process for our Swiss clients. The change ensures accurate reporting to Swiss tax authorities, reducing the risk of errors and improving compliance. This update impacts the Swiss payroll module.
Original PR description
Forward-Port-Of: odoo/enterprise#111143
This update fixes an issue where repositioning PDF signs within the Odoo interface caused erratic resizing behavior due to multiple event listeners. The change ensures only one resize listener is attached per sign, resulting in a more reliable and predictable resizing experience for users. This enhances the overall usability of the PDF sign functionality.
Original PR description
Previously, repositioning a sign item inside the PDF iframe would attach multiple resize event listeners. This led to inconsistent and unintuitive resizing behavior. This commit ensures that only a single resize listener is registered per item, avoiding duplicated handlers and restoring stable interaction. task-6048759 Forward-Port-Of: odoo/enterprise#111146
This update fixes an issue in how tax reports calculate period boundaries, particularly when using 'trimester' tax periods. The change ensures accurate reporting by correctly identifying the relevant tax period for calculations, preventing incorrect values being displayed in reports. This improves the reliability of financial reporting.
Original PR description
To reproduce the issue: - Setup tax periodicity to "trimester" - Create a report evaluating something with previous_tax_period date_scope (real cases tend to do that for carryover ; see monthly…
To reproduce the issue: - Setup tax periodicity to "trimester" - Create a report evaluating something with previous_tax_period date_scope (real cases tend to do that for carryover ; see monthly Italian tax report for an example) - Create the appropriate data so that in the current trimester, the report line evaluates to 42, and to 1 in the previous trimester - Open the report for the second month of the trimester => The line has value 42, while it should have 1. This happens because the date bounds for previous_tax_period were computed too naively, considering the date_from was always the first day of the tax period. The first day of the second month of the trimester, it's not the case, and we return the period boundaries of the day before that day. That day is the last day of the first month of the trimester, but belongs to the same trimester, so it's the same tax period. Therefore, we display the value of the current tax period, which is wrong. Forward-Port-Of: odoo/enterprise#111330 Forward-Port-Of: odoo/enterprise#110504
9 changes
Resolved issues and error corrections
This update resolves an issue where the bulk payments feature would crash if a bank journal wasn't properly connected. A new user message will now appear, guiding users to ensure their bank account is linked before attempting to check the status of a payment batch. This improves the user experience and prevents unexpected errors.
Original PR description
This commit: https://github.com/odoo/enterprise/commit/c9cc89f58f7d98396afac3bdacfeff9b00a02a21 introduce the initiate bulk payments feature. When selecting a batch you can also check the status of this batch. But for the moment, if you select a batch that is not connected to a bank, the action will traceback with a redirect. This commit will add a user error to warn the user than the journal needs to be connected to a bank. task-6009083 Forward-Port-Of: odoo/enterprise#111327 Forward-Port-Of: odoo/enterprise#109956
This update resolves an error that occurred when using the 'hr_expense_stripe' module with unsupported currencies like INR. The module will no longer attempt to create a 'Stripe Issuing' journal, preventing the error and allowing users to access the invoicing dashboard. The fix ensures a stable experience when using specific currency configurations.
Original PR description
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to…
Currently, an error occurs when a user opens the invoicing dashboard after activating the `hr_expense_stripe` module for Stripe card issuing with only unsupported currencies active. Steps to reproduce: (19.0) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` - Create New company > Set `Country` and `Currency` (eg: India and INR) > Switch to New company > Open `Invoicing` you will get the error. Steps to reproduce: (saas-19.1) - Install `account` module - Set Company currency to `INR` and deactivate `USD` in currencies. - Install `hr_expense_stripe` > Open `Invoicing` you will get the error. Traceback: `ValueError: Expected singleton: res.currency()` In this [PR], the behavior is such that if `company.stripe_currency_id` is not set, we do not create the "Stripe Issuing". In 19.0, `@template` was executed after the post-init hook, and we were preventing the creation of the [journal] at that stage. However, when a new company is created, the template data is automatically loaded for companies with a matching chart of accounts. As a result, the `stripe_issuing_journal` is created, which leads to the error. However, in saas-19.1, due to recent improvements in a [commit], the `@template` will now loads data for companies without post init hook. As a result, the `stripe_issuing_journal` is being created, and we are encountering an error. Solution: - The`Stripe Issuing` journal will no longer be created on installing the module. - For existing databases, we will use the company currency as a fallback value to ensure that a valid currency is applied. [PR]: https://github.com/odoo/enterprise/pull/96271 [journal]: https://github.com/odoo/enterprise/blob/fea009f98885a97439edfea75376b7323c8c9a03/hr_expense_stripe/models/res_company.py#L186-L187 [commit]: https://github.com/odoo/odoo/pull/228950/changes/21fd14ed5e8bdd2cf203d466069437a62a87f2bd sentry-7284934493 Forward-Port-Of: odoo/enterprise#108436
This update enhances product pricing by now sending unit of measure information (price per unit and quantity) to the system. It also resolves a previous issue where product tag updates weren't automatically triggered by changes to product barcodes or linked products, ensuring accurate pricing and tag synchronization.
Original PR description
If units of measure is configured, we now send the price per unit and the amount of unit for the current product. This commit also fixes an issue where we didn't call pricer API to update tags if we updated the tag barcode, or if we updated the product linked to it. Task-5129442
This update ensures the topbar menu accurately reflects the menu selected through Odoo's AI Agent. Previously, the topbar didn't update when an AI Agent opened a menu, leading to a disjointed user experience. This fix corrects this behavior, providing a more consistent and intuitive interface for users.
Original PR description
Purpose: -------- When a menu (view) was opened through an AI Agent, the menu in the topbar was not updated. This commit fixes this behaviour by setting the menu when the menu's action has been loaded Task-6017607 Forward-Port-Of: odoo/enterprise#109929
This update corrects a bug in the refund processing for multi-line orders. Previously, the system incorrectly summed line amounts, leading to inaccurate comparisons and potential refund failures due to rounding discrepancies. This change ensures refunds are calculated correctly, preventing order discrepancies and improving financial accuracy.
Original PR description
Before this commit, the some of individual line amounts were being summed to compare against the original order total when processing a refund. This could lead to incorrect comparisons due to rounding issues, resulting in errors when attempting to refund orders with multiple lines. <img width="626" height="288" alt="image" src="https://github.com/user-attachments/assets/e1bdc126-64d9-4b9a-bd16-2b97ac75e40c" /> opw-5433201 Forward-Port-Of: odoo/enterprise#109124 Forward-Port-Of: odoo/enterprise#105301
This update automatically calculates and transmits the necessary commission payments related to employee compensation for Swiss payroll (ELM). Previously, this calculation was manual, and this change streamlines the process, ensuring accurate and timely reporting to Swiss tax authorities. This improves compliance and reduces the risk of errors.
Original PR description
task-6050810 Forward-Port-Of: odoo/enterprise#111143
This update resolves an issue where the payroll module wouldn't function correctly if only the core payroll components were installed. The `l10n_mx_min_wage_zone` field has been moved from a separate module to the main payroll module, ensuring compatibility and proper operation for all users.
Original PR description
The `l10n_mx_min_wage_zone` field is used in `l10n_mx_hr_payroll`, but it was originally defined in `l10n_mx_hr_payroll_account_edi`. This causes errors when a user only installs the `l10n_mx_hr_payroll` module, as the field is missing. Related commit: 11bb6db4884083b3f48582b749c01ae75a09cf66 target: master task-6047772
Previously, when users uploaded multiple files to a WhatsApp Discuss channel, only the first file was delivered. This update corrects this issue by preventing the sending of multiple attachments, ensuring all files are successfully transmitted to the recipient. This improves the reliability of WhatsApp communication within Odoo.
Original PR description
Multiple attachments uploaded simultaneously to a WhatsApp Discuss channel result in only the first being delivered to the recipient. ### Steps to reproduce 1. Drag and drop multiple files into a…
Multiple attachments uploaded simultaneously to a WhatsApp Discuss channel result in only the first being delivered to the recipient. ### Steps to reproduce 1. Drag and drop multiple files into a WhatsApp Discuss channel. 2. Send the message. -> Odoo shows all files, but only the first reaches the destination. ### Cause WhatsApp's API permits only one media object per message. Odoo's "Composer" enforces this by blocking uploads if an attachment is already present. However, it only evaluates the *current* state; dropping multiple files into an empty composer passes the check because the count is zero. On the server, the WhatsApp backend (constrained by the API) is hardcoded to send only the first attachment, silently discarding the rest. ### Fix Updated frontend validation to inspect the incoming file list during drop and paste actions. The process is now blocked if the total of existing plus incoming files exceeds one, ensuring the user is notified and preventing silent data loss. opw-5889035 Forward-Port-Of: odoo/enterprise#111001 Forward-Port-Of: odoo/enterprise#107424
This update enhances security within Odoo's spreadsheet modules by ensuring that users only have access to data based on their permissions. The changes align search filters with access controls, preventing unauthorized data viewing. This improves data security and protects sensitive information within spreadsheet applications.
6 changes
Resolved issues and error corrections
This update resolves an issue preventing invoices with the ICBPER tax code from generating correctly. The fix addresses a technical problem related to how the system handles fixed taxes, ensuring invoices with this tax now process without errors. This improves the reliability of invoice generation for Peru customers.
Original PR description
**Steps to reproduce:** 1. Install module `l10n_pe_edi`. 2. Switch company to PE. 3. Create a tax: - Name: ICBPER - Amount type: Fixed - Code: ICBPER - Amount: 0.5(e.g.) - Set the tax group to ICBPER…
**Steps to reproduce:**
1. Install module `l10n_pe_edi`.
2. Switch company to PE.
3. Create a tax:
- Name: ICBPER
- Amount type: Fixed
- Code: ICBPER
- Amount: 0.5(e.g.)
- Set the tax group to ICBPER (In Advance Option)
4. Create a invoice and add a product with ICBPER tax.
5. Post the invoice and click "Process Now" (at header).
**Issue:**
Processing the invoice raises:
AttributeError: 'dict' object has no attribute '_get_downpayment_lines'
**Cause:**
When `fixed_taxes_as_allowance_charges` is True, `_setup_base_lines()` calls `_turn_emptying_taxes_as_new_base_lines()`, which splits fixed taxes (e.g., ICBPER) into separate base lines.
During this process, `base_line['record']` is no longer the original `account.move.line` record. Instead, it becomes a dictionary containing record under `base_line['record']['record']`.
- With the flag enabled: `base_line['record']` -> dict `line._get_downpayment_lines()` -> AttributeError
- With the flag disabled: `base_line['record']` -> `account.move.line``line._get_downpayment_lines()` -> works correctly
The Peru EDI implementation directly accesses `base_line['record']` expecting an `account.move.line`. The the nested dict structure causes the crash during file generation.
**Solution:**
Override `_add_invoice_config_vals()` to explicitly set `fixed_taxes_as_allowance_charges = False`
- Add test to ensure invoices with ICBPER fixed taxes generate XML without error
**opw-5809939**This update fixes an issue where users weren't receiving email notifications for signature requests when their notification preferences were set to 'inbox'. Now, all signature requests will trigger email notifications, ensuring signers are promptly informed. This change maintains in-app visibility for users who track requests within Odoo.
Original PR description
When a user's notification preference is set to "inbox", no email is sent, which may prevent signers from being notified of signature requests. This commit enforces sending email notifications for signature requests regardless of user notification settings. Notifications are still created in Odoo, preserving in-app visibility for users who rely on it. task-6041834
This update automatically calculates and transmits the necessary commission payments related to employee earnings for Swiss payroll (l10n_ch_hr_payroll). Previously, this calculation was manual, and this change streamlines the process, ensuring accurate and timely reporting to Swiss tax authorities. This improves compliance and reduces the risk of errors.
Original PR description
Forward-Port-Of: odoo/enterprise#111143
This update fixes an issue where DATEV exports were inaccurate when a move line's account was changed. Now, updating a move line's account automatically recalculates the DATEV main account, ensuring the exported data correctly reflects the current financial accounts. This prevents duplicate lines in DATEV reports.
Original PR description
Description of the issue this commit addresses: When the account of a move line is updated (e.g. replacing the suspense account with the actual one), l10n_de_datev_main_account_id was not recomputed which leads to an incorrect DATEV export with duplicate lines. Desired behavior after this commit is merged: Changing the account_id of a move line recomputes l10n_de_datev_main_account_id so that the exported DATEV data reflects the current accounts of the move.
This update resolves an issue where night shift slots (e.g., 20PM - 4AM) were not visible in the weekly planning view. The fix adjusts how the system displays multi-day slots, ensuring all scheduled hours are accurately shown. This improves the planning experience for employees with flexible work arrangements.
Original PR description
**Steps to reproduce** 1. Have an employee using a flexible schedule 2. Create a slot from e.g. 20PM to 4AM for this employee. Make sure this is the only slot that week for the employee. 3. Publish…
**Steps to reproduce** 1. Have an employee using a flexible schedule 2. Create a slot from e.g. 20PM to 4AM for this employee. Make sure this is the only slot that week for the employee. 3. Publish the Schedule and send it to the employee. Open the outgoing mail to access the link to the planning view. Issue: the slot is not visible in the week view. **Cause** https://github.com/odoo/enterprise/blob/04a885dbb6eed96297cb5ce9a155ebf8e169427c/planning/controllers/main.py#L193-L194 The `event_hour_min` and `event_hour_max` returned by `planning_get` and used to control the min/max hours displayed in the week view, didn't account for slots over multiple days. For a slot between 20pm and 4am, the `event_hour_max` should be the end of the day, and the `event_hour_min` should be the start of the day. **Solution** - we change the `event_hour_min` and `event_hour_max` for multi-day slots to display the full days in the week view - the previous point has the drawback of displaying the full days for non-flexible employees even when not necessary. This is because `slots_start_datetime` and `slots_end_datetime` contained the `planning.slot` start and end. Instead, we can look at the actual slot values displayed (by `_get_slots_vals`). For example, a 5 day slot for a non-flexible employee may contain actual slot values corresponding to a typical 8-17 working day. opw-5245985 Forward-Port-Of: odoo/enterprise#99784
This update ensures that payroll payslips with analytic rules are correctly anonymized, preventing individual employee lines from appearing in aggregated accounting moves. The fix addresses a technical issue related to how analytic distributions are processed, enhancing data privacy and compliance. A new test has been added to verify the fix.
Original PR description
The Batch Account Move Lines option in the settings is used to aggregate together the different payslips of a payrun and to create only one move with aggregated lines, per account. This is done to…
The Batch Account Move Lines option in the settings is used to aggregate together the different payslips of a payrun and to create only one move with aggregated lines, per account. This is done to enforce privacy and avoid having lines for each employee in the payrun. If salary rules with analytic distributions are involved, though, the lines are not merged and we lose the anonimity.
This happens because in the _get_existing_lines funciton, that should return the lines to be merged with the input line (line), the condition for the rules that have an analytic distribution is wrong.
In particular, the condition is wrong because the
distribution_analytic_account_ids field is a recordset of the accounts, while line_id['analytic_distribution'] is a dictionary with keys that are comma separated strings of the ids of the accounts, with values reflecting the percentage.
For example, if a rule has one analytic distribution for 40% and involving accounts 13,7 and 12 + another analytic distribution for 60% involving accounts 3 and 5, line_id['analytic_distribution'] will be {'13,7,12': 40.0, '3,5': 60.0} while distribution_analytic_etc will be a recordset containing (13,7,12,3,5). To fix the problem and keep everything inline, we extract the logic to a new function, where we first unravel the ids from the keys of the dictionary and only then try to match them to the values in the recordset.
Task: 604395717 changes
Resolved issues and error corrections
This update resolves a bug in Odoo's Web Studio where invisible fields would lose their visibility settings when toggling the 'Show Invisible Elements' option. The fix ensures that invisible field attributes are correctly retained and applied within the studio editor, improving user experience and data consistency.
Original PR description
Steps to reproduce ================== - Install contacts,web_studio - Login as admin - Go to contacts - Open any record - Open studio - Click on any field - Add the "Role / Portal" group - Toggle the…
Steps to reproduce ================== - Install contacts,web_studio - Login as admin - Go to contacts - Open any record - Open studio - Click on any field - Add the "Role / Portal" group - Toggle the "Show invisible Elements" checkbox - Click on the same field => The field is marked as invisible - Add an invisible condition => The invisible condition is lost (but still applied on the view) Cause of the issue ================== In studio, when fetching the view, the invisible attribute is set to True when the user does not have access to the field (when he is not part of the groups). The goal is to make the field invisible in studio unless the "Show invisible Elements" is toggled. But this causes the actual value of the invisible attribute to be lost. Note that this also applies to the column_invisible attribute. Solution ======== If an invisible/column_invisible attribute is present on the nodes with missing access, we copy the actual value to the `actual_invisible` attribute. We then use that value in the editor, when present. opw-6026971
This update automatically calculates and includes the necessary commission deductions for Swiss payroll reports (ELM) based on employee data. This ensures accurate reporting to tax authorities, addressing a previous reporting issue and improving compliance with Swiss regulations. The change impacts the Swiss payroll module.
Original PR description
Forward-Port-Of: odoo/enterprise#111143
This update corrects a bug in the MX CFDI invoice generation process. Previously, the required 'NumeroPedimento' information was missing, leading to invoice rejection. The fix ensures that the correct pedimento number is included in the generated CFDI documents, complying with Mexican tax regulations.
Original PR description
The numero pediemento is missing in invoices CFDI Step to reproduce: - in MX company with l10n_mx_edi_landing - create an invoice - add product with a custom number (with 2 spaces between number ranges) - Confirm and send The generated CFDI is missing the `InformacionAduanera` node and its `NumeroPedimento` attribute. Cause: Node and attribute are filled in the CFDI from the 'complementos_list'. Which is a copy of each base_line 'l10n_mx_cfdi_values'. The list was missing the `informacion_aduanera_list`. opw-5949684
This update resolves an issue where dropship orders between companies were not accurately reflecting delivered quantities. The fix adjusts how the system tracks moves during dropship transactions, ensuring the correct quantity is displayed on the sale order line. This ensures accurate order fulfillment and reporting across inter-company sales.
Original PR description
**Steps to reproduce:** - Make sure you have 3 companies (comp A, B and C) - Navigate to Settings/Users & Companies/ Companies - for each company in the 'Inter Company Transactions' tab: check…
**Steps to reproduce:** - Make sure you have 3 companies (comp A, B and C) - Navigate to Settings/Users & Companies/ Companies - for each company in the 'Inter Company Transactions' tab: check 'generate Sale Orders', 'generate purchase orders' and 'synchronize Deliveries to your receipts' then select a warehouse and a receipt operation type From company A - create a storable product - in the Purchase tab, set the company B as a vendor From company B - in the Purchase tab of the product, set company C as a vendor From company C - set a positive on hand quantity From Company A - create a SO for 1 quantity of your product - on the sale order line, unhide de route_id column and set it to dropship - confirm the SO and the linked PO From company B - on the SO created with company A as customer (you might need to remove the 'my quotations filter to find it), set the dropship route in the route_id column of the sale order line - confirm the SO and the linked PO From company C - confirm SO created with company B as customer - validate the delivery From company B - validate the dropship **Current behavior:** the quantity delivered on the sale order line is 0 **Expected behavior:** it should be 1 **Cause of the issue:** inside _compute_qty_delivered, we fetch the incoming and outgoing moves using _get_outgoing_incoming_moves() https://github.com/odoo/odoo/blob/b936b64ed0217909ff96a1b28d1370f5064be46a/addons/sale_stock/models/sale_order_line.py#L200 There, for the move of the dropship picking, inside the if condition, move._is_dropshipped_returned() will be True https://github.com/odoo/odoo/blob/b936b64ed0217909ff96a1b28d1370f5064be46a/addons/sale_stock/models/sale_order_line.py#L348-L354 That's because the move is going from transit to transit https://github.com/odoo/odoo/blob/b936b64ed0217909ff96a1b28d1370f5064be46a/addons/stock_account/models/stock_move.py#L186-L195 So it will not be added to the outgoing moves and qty_delivered will stay 0. **fix** is_dropshipped_returned should not prevent the move to be added to the outgoing moves if is_dropshipped() is aslo true (i.e. it's a transit to transit move) opw-5023215
This update fixes a reporting issue where the KMD INF report incorrectly included partners with low turnover. Now, the report only includes partners with total invoices and credit notes exceeding 1,000 EUR, ensuring more accurate financial reporting. The calculation considers both invoices and credit notes, and also accounts for Part B transactions.
Original PR description
The KMD INF report should only include partners whose total turnover for the period reaches 1,000 EUR. Before this PR: - The report did not check this threshold, so partners below €1,000 were still shown. After this PR: - The threshold is now calculated correctly based on specific rules: - The threshold is calculated separately for invoices and credit notes per partner. - If invoices total base amount >= €1,000 OR credit notes total base amount >= €1,000, both invoices and credit notes are included in the report - The same logic applies to bills and refunds in Part B. task-5373606 Forward-Port-Of: odoo/enterprise#101333
This update fixes an issue where repositioning PDF signs would cause multiple resize events, leading to unpredictable behavior. The change ensures only one resize listener is attached per sign, resulting in a more stable and reliable resizing experience for users. This improves the overall usability of the PDF sign functionality.
Original PR description
Previously, repositioning a sign item inside the PDF iframe would attach multiple resize event listeners. This led to inconsistent and unintuitive resizing behavior. This commit ensures that only a single resize listener is registered per item, avoiding duplicated handlers and restoring stable interaction. task-6048759 Forward-Port-Of: odoo/enterprise#111146
This update corrects a legal requirement for GT EDI invoices. Previously, crucial 'complementos' data were missing from the PDF invoices generated for specific document types (FCAM, FCAP, FESP), while they were present in the XML. This change ensures compliance and accurate invoice generation.
Original PR description
**PROBLEM** For some documents types, the "complementos" are not present in the pdf while they are present in the xml. It's legally required that they are added in the pdf. **STEP TO REPRODUCE** 1. Install l10n_gt_edi. 2. Create an customer invoice. 3. Set the document type to FCAM, FCAP, or FESP. 4. Send the invoice using the cfdi. 5. download the xml and the pdf, notice the complementos are in the xml, but not in the pdf. opw-5970285
This update fixes an issue where the SDWorx payroll report wasn't correctly accounting for public holidays. The change ensures that employee attendance is accurately calculated, reflecting scheduled holidays and improving payroll report accuracy. This resolves a discrepancy in reporting for employees on leave during public holidays.
Original PR description
### Steps to reproduce: - Setup a public holiday in a month January for example - Add a leave for an employee for the whole Month of January - Export the SDworx report - Notice for the day of the public holiday, it is shown as a normal attendance ### Cause: When checking leaves for the SDWorx report we only check hr.leave we don't check resource.calendar.leaves ### Fix: We take resource.calendar.leaves now into account to make sure we add public holidays to the report when exporting it opw-5500070 Forward-Port-Of: odoo/enterprise#106065
This update resolves an issue where users were directed to the wrong document form view when configuring PEPPOL document syncing settings. The change adds a dedicated Kanban view for managing PEPPOL documents, ensuring users access the correct interface for organizing and accessing these important files. This improves the user experience and streamlines document management.
Original PR description
Before this commit: clicking through on the setting of configuring the folder to sync peppol documents would lead to the document form view instead of the kanban view. Task-6040802
This update fixes a bug in the loyalty module's promotion calculation for Chilean sales using UF or Dollars. Previously, promotions wouldn't apply when product prices were below 0.50 UF due to incorrect currency rounding. Now, promotions will correctly identify and apply discounts, ensuring accurate reward calculations.
Original PR description
Description of the issue/feature this PR addresses: When using the loyalty module with Chilean localization and a sale in UF or Dollars, an error occurs when calculating the promotion amount. When…
Description of the issue/feature this PR addresses: When using the loyalty module with Chilean localization and a sale in UF or Dollars, an error occurs when calculating the promotion amount. When the system evaluates whether a promotion is applicable, it appears to be taking the value of the sale line after applying the company currency rounding instead of the sale order currency rounding. In the case of Chile with the peso currency, where rounding is applied to the unit, if the value of a line is less than 0.50 UF, the system rounds it to 0. By interpreting the line value as zero, the promotion engine does not recognize the existence of valid products and the "Promotions/Reward" button does not display any available options, even though the program conditions are met. The root cause of the problem is that the `compute_all` method of taxes is being called without specifying the currency, which causes it to use the company currency instead of the sale order currency. Current behavior before PR: - Create a Promotions program (Discount & Loyalty) that applies, for example, a 10% discount without complex minimum restrictions. - Create a Sales Order and add a product line whose unit price is less than 0.50 (e.g. 0.34 UF). - Click on the "reward" button. Result: No available promotions are shown or it does not apply if there is only one active promotion. Desired behavior after PR is merged: - Create a Promotions program (Discount & Loyalty) that applies, for example, a 10% discount without complex minimum restrictions. - Create a Sales Order and add a product line whose unit price is less than 0.50 (e.g. 0.34 UF). - Click on the "reward" button. Result: The button now detects the promotion and allows it to be applied. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a validation error that occurred when creating invoices from POS orders with cash rounding enabled. Previously, non-cash payment methods triggered an error due to rounding logic attempting to apply. Now, the system correctly avoids rounding for non-cash payments, ensuring invoices are created without this issue.
Original PR description
## Issue before this commit: Creating an invoice from a POS order with **Cash Rounding enabled only for cash payment methods** raised an unexpected validation error: > *"The operation cannot be…
## Issue before this commit: Creating an invoice from a POS order with **Cash Rounding enabled only for cash payment methods** raised an unexpected validation error: > *"The operation cannot be completed: Missing required account on accountable line."* This happened when the order was paid using a **non-cash payment method**, but rounding logic was still applied. ## Steps to Reproduce: 1. Install the `point_of_sale` module. 2. Go to POS Configuration → Settings: * Enable **Cash Rounding** * Set a **Rounding Method** * Enable **Only on cash methods** 3. Create a product: * Sale Price: 260 * Tax: 6% 4. Open a POS session. 5. Add the product to an order. 6. Apply a discount (e.g., 1.123). 7. Pay using a **non-cash payment method** (journal not marked as cash). 8. Enable **Invoice** and validate the order *(or create the invoice later from the Orders menu)* ## Cause of the Issue: While `_prepare_invoice_vals` correctly avoids setting `invoice_cash_rounding_id` for non-cash payments, `_create_invoice` still executes rounding logic whenever cash rounding is enabled on the POS configuration. This leads to a mismatch where: * No rounding configuration is set on the invoice * Rounding logic still attempts to create/update rounding lines * Required accounts (profit/loss) cannot be determined * A validation error is raised due to missing account on the generated line ## With This Commit: The rounding logic in `_create_invoice` is now guarded by checking the presence of `invoice_cash_rounding_id`. This ensures rounding is only applied when properly configured and avoids unexpected validation errors for non-cash payment invoices. Steps To Reporduce: [Video Link](https://drive.google.com/file/d/10ticlUW5i5pbu_oDDPqR-jg0hVcNWf3Z/view?usp=sharing) opw-6005320 opw-5951991 opw-6036870
This update resolves an issue where dropship orders weren't accurately reflecting delivered quantities. The fix adjusts how the system tracks moves during dropship transactions, ensuring the correct quantity is displayed on sale order lines. This ensures accurate order fulfillment reporting.
Original PR description
**Steps to reproduce:** - Make sure you have 3 companies (comp A, B and C) - Navigate to Settings/Users & Companies/ Companies - for each company in the 'Inter Company Transactions' tab: check…
**Steps to reproduce:** - Make sure you have 3 companies (comp A, B and C) - Navigate to Settings/Users & Companies/ Companies - for each company in the 'Inter Company Transactions' tab: check 'generate Sale Orders', 'generate purchase orders' and 'synchronize Deliveries to your receipts' then select a warehouse and a receipt operation type From company A - create a storable product - in the Purchase tab, set the company B as a vendor From company B - in the Purchase tab of the product, set company C as a vendor From company C - set a positive on hand quantity From Company A - create a SO for 1 quantity of your product - on the sale order line, unhide de route_id column and set it to dropship - confirm the SO and the linked PO From company B - on the SO created with company A as customer (you might need to remove the 'my quotations filter to find it), set the dropship route in the route_id column of the sale order line - confirm the SO and the linked PO From company C - confirm SO created with company B as customer - validate the delivery From company B - validate the dropship **Current behavior:** the quantity delivered on the sale order line is 0 **Expected behavior:** it should be 1 **Cause of the issue:** inside _compute_qty_delivered, we fetch the incoming and outgoing moves using _get_outgoing_incoming_moves() https://github.com/odoo/odoo/blob/b936b64ed0217909ff96a1b28d1370f5064be46a/addons/sale_stock/models/sale_order_line.py#L200 There, for the move of the dropship picking, inside the if condition, move._is_dropshipped_returned() will be True https://github.com/odoo/odoo/blob/b936b64ed0217909ff96a1b28d1370f5064be46a/addons/sale_stock/models/sale_order_line.py#L348-L354 That's because the move is going from transit to transit https://github.com/odoo/odoo/blob/b936b64ed0217909ff96a1b28d1370f5064be46a/addons/stock_account/models/stock_move.py#L186-L195 So it will not be added to the outgoing moves and qty_delivered will stay 0. **fix** is_dropshipped_returned should not prevent the move to be added to the outgoing moves if is_dropshipped() is aslo true (i.e. it's a transit to transit move) opw-5023215
This update fixes an issue where archived channels were not searchable, leading to access problems. Now, users can perform actions on all channels, including those that have been archived, improving channel management and usability. This resolves a previous error impacting channel access.
This update fixes an issue where formatted notes in customer records within the Point of Sale module were not being displayed correctly. The fix ensures the necessary HTML editor runtime is included in the POS asset bundle, allowing users to properly edit and view formatted notes in the Customer Edit Details dialog. This enhances the user experience for managing customer information within Point of Sale.
Original PR description
Ensure the POS asset bundle includes the html editor runtime (and DOMPurify) so partner Internal Notes are rendered/edited correctly in the Edit Details dialog. Steps to reproduce: ------------------- * Install only Point of Sale on a fresh DB (community setup). * Add a formatted note in a customer Internal Notes field. * Open POS -> Customer -> Edit Details -> Internal Notes. > Observation: note is shown as raw HTML / fallback textarea instead of rendered HTML. Why the fix: ------------ `point_of_sale.assets_prod` did not include the html editor runtime. Adding html editor to that bundle restores proper HTML rendering/editing. Test note: ---------- No automated test added: the issue depends on runtime asset loading and it differs in POS vs backend/test environment opw-5938168
This update resolves a previous issue where different addons could overwrite each other's translations for the same term, leading to inconsistent language displays. The fix ensures that translations are correctly prioritized based on the addon that's currently being used, providing a more reliable and accurate user experience. This improves the overall quality and consistency of the Odoo web interface.
Original PR description
When multiple addons provide different translations for the same term (e.g. "Table" → "Mesa" in pos_restaurant vs "Tabla" in web_editor), the last-loaded module would silently overwrite the others.
Fix by storing scoped keys ("addon\x04term") in translatedTerms for any module that conflicts with a previously loaded one. The module loader now intercepts require("@web/core/l10n/translation") and returns a module-bound _t via createModuleT(addon), so every JS import of _t resolves translations against the importing addon's scope — including calls inside method bodies, not just at module init time. OWL templates continue to resolve via this.templateName in the CodeGenerator, which takes precedence inside createModuleT.
opw-5970092
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update corrects a bug where manual Stripe payments (SEPA Direct Debit) were immediately canceled despite transactions remaining in 'Pending' status. This prevented subscriptions from correctly reflecting payments and risked automatic closures after 90 days. The fix ensures payments remain in the correct 'Pending' state until Stripe confirms the transaction.
Original PR description
**Problem:** When manually registering a payment using a Stripe SEPA Direct Debit token, the associated `account.payment` is immediately canceled, even though the Stripe transaction is in "Pending"…
**Problem:** When manually registering a payment using a Stripe SEPA Direct Debit token, the associated `account.payment` is immediately canceled, even though the Stripe transaction is in "Pending" status. Later, when Stripe confirms the transaction, the payment remains canceled, leading to subscription closures after 90 days of apparent non-payment. **Steps to reproduce:** 1) Set a customer address to Belgium and add a SEPA Direct Debit payment token via Stripe. 2) Change the company currency to euro. 4) Create a manual invoice for that customer. 5) Pay the invoice using the pre-configured Stripe SEPA token. 6) Observe the `account.payment` is immediately canceled despite the transaction being "Pending". 7) When Stripe confirms the transaction, the payment stays canceled. **Cause:** In `account_payment.action_post()`, after sending the payment request, all payments whose transaction state was not `done` were canceled. For asynchronous payment methods like SEPA Direct Debit, the transaction starts in `pending` (not `done`), so the payment was wrongly canceled. **Solution:** - Only cancel payments whose transaction ended in a failure state (not in `done`, `pending`, or `authorized`), so pending/authorized payments stay in draft/in_process. opw-5934381 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update ensures the sale dashboard accurately displays all completed POS orders, regardless of their status. Previously, orders with statuses like 'done' were not visible. This change corrects a discrepancy in how the dashboard processes order status information, providing a more complete view of sales data.
Original PR description
Step to reproduce: - install spreadsheet_dashboard_sale and pos_sale - create a order in pos , invoice it too - open sale dashboard Observation: - the order fulfilled in pos, does not reflect in…
Step to reproduce: - install spreadsheet_dashboard_sale and pos_sale - create a order in pos , invoice it too - open sale dashboard Observation: - the order fulfilled in pos, does not reflect in dashboard Cause: - sale has 4 status i.e ["draft", "sent", "sale", "cancel"] - when pos_sale is installed, new status oders are added i.e ['paid', 'invoiced', 'done'] - sale dashboard pivot relies on sale defined status only, which so not consider orders that have status in ['paid', 'invoiced', 'done'] Fix: - fix the domain of pivots such that, it will now accept other orders too **Before:** <img width="1058" height="277" alt="image" src="https://github.com/user-attachments/assets/e58c88fa-5ad3-4194-9f9c-ddf41f2f73de" /> <img width="1116" height="190" alt="image" src="https://github.com/user-attachments/assets/259e0347-5d5b-4d5c-9aeb-74102aa4becd" /> <br/> **After** <br/> <img width="1137" height="232" alt="image" src="https://github.com/user-attachments/assets/406b71a5-1dd8-4164-9d4e-4f0bca34c9e8" /> <img width="1125" height="235" alt="image" src="https://github.com/user-attachments/assets/fded3203-7d72-45ea-b5aa-142ebcd52136" /> opw-5487654 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
7 changes
Resolved issues and error corrections
This update automatically calculates and transmits the necessary commission payments for Swiss payroll (ELM) declarations. Previously, this calculation was manual, and this change streamlines the process, ensuring accurate and timely reporting to tax authorities. This improves compliance and reduces the risk of errors related to commission calculations.
Original PR description
task-6050810
This update resolves a bug preventing users from correctly changing the 'Recurring' status on subscription products with existing sales orders. The fix ensures the change is reverted properly, preventing incorrect data and improving data integrity. This update impacts subscription management functionality.
Original PR description
**Problem:** When attempting to change "Recurring" on products in the form view, if there are confirmed SOs, the change should be reverted and a message should appear explaining this. However, there is a bug in how the change is reverted where it takes the current form value of the field. This cannot be trusted as it's possible to trigger another onchange before the first one resolves, so the second onchange is based on the wrong value. **Steps to Reproduce:** - w/Demo Data, go to product "Office Cleaning Service (SUB)" (This is a subscription product which has confirmed SOs) - Quickly click the checkbox for "Recurring" twice -> Two warnings appear, but Recurring is False and can be saved **Solution:** Instead of reading the current form value and setting its opposite, we can revert to the current value on the server.
This update fixes an issue where the SDWorx payroll report didn't account for public holidays. The change ensures that employee attendance is correctly calculated, including days when the company is closed for holidays, leading to more accurate payroll reporting.
Original PR description
### Steps to reproduce: - Setup a public holiday in a month January for example - Add a leave for an employee for the whole Month of January - Export the SDworx report - Notice for the day of the public holiday, it is shown as a normal attendance ### Cause: When checking leaves for the SDWorx report we only check hr.leave we don't check resource.calendar.leaves ### Fix: We take resource.calendar.leaves now into account to make sure we add public holidays to the report when exporting it opw-5500070
This update resolves an issue where scanning a barcode with a different serial number than the reserved one didn't create a new lot in stock. The fix ensures that the correct lot is always used when scanning in batches, preventing incorrect inventory tracking. This improves the accuracy of stock management.
Original PR description
Issue ----- When processing batches in barcode, scanning a BC with a different SN than the reserved one does not lead to creating a new lot in stock. The reserved one is still the one getting taken…
Issue
-----
When processing batches in barcode, scanning a BC with a different SN than the reserved one does not lead to creating a new lot in stock. The reserved one is still the one getting taken regardless of setting.
Steps to reproduce
-----
- Enable GS1 nomenclature, lots & batches
- Go to Inventory > Configuration > Operation Types > Delivery Orders
- Enable Lots/Serial Numbers > Create New
- Create a product
- Barcode 23456789012344
- Tracked by SN
- 1 in stock (SN 1234)
- Create a delivery for the product and add it to a batch
- Open the batch in barcode
- Scan 012345678901234410BATCHSN1
- Confirm the delviery
- Go back to the picking and see the lines' details
> The line used the reserved SN
Cause
-----
The existing line gets matched in `_findLine`
https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/stock_barcode/static/src/models/barcode_model.js#L1085
because none of the conditions before
https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/stock_barcode/static/src/models/barcode_model.js#L1402
get matched. This is unexpected but necessary for batches, as it ensures barcode correctly swaps to the correct picking in the batch. If the line was not matched we would be creating a new line in the same picking than the last scanned line, regardless of which picking the reservation is made in.
Because a line is matched, we have to force its' `lot_id` to `false` so that the new one gets created (`lot_name` is used for display but `lot_id` takes precedence).
-----
Ticket:
opw-5216921This update optimizes how Odoo searches for products during the 'explode' process, which is a key step in managing product components. By batching database queries, the change reduces the time spent on this process, resulting in faster product searches. This improvement primarily impacts the MRP module.
Original PR description
When searching product based on the qty_available field, a lot of time is spent in explode() calls. In the explode() method, we call _bom_find() for each bom involved. This method only depends on the picking_type_id and company_id of the bom. Thus we could batch it and call the method once per tuple (picking_type_id, company_id). Benchmark: |No BoM | No product variants | Before | After | |-------|------------|--------|-------| | 1700 | 13000 | 80s | 40 s | opw-6017527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a validation issue that occurred when using Recupel tax on invoices with negative line items. The fix ensures that the generated XML invoices correctly represent the tax treatment, preventing validation failures. This ensures compliance with PEPPOL standards and accurate invoice processing.
Original PR description
**PROBLEM** If you set a recupel tax (fixed tax affecting base) and use it on a negative line, the generate xml will not pass validation. **STEP TO REPRODUCE** 1. Setup Peppol. 2. Create a recupel tax (fixed tax of 1€, affecting the base). 3. Create an invoice with a negative line, with a VAT and the recupel tax. 4. Send the invoice using peppol, and validate the xml. 5. Notice the xml doesn't pass validation. **CAUSES** 1. The negative fixed tax should be an allowance, but is marked as a charge in the xml. 2. Only fixed taxes that are charges influences the line_extension_amount, but it should also be the case with negative fixed taxes. 3. Negative fixed taxes should have a ChargeAllowanceReasonCode that is in the AllowanceReasonCode list. opw-5955289 Forward-Port-Of: odoo/odoo#252716
This update fixes an issue where exchange differences weren't correctly recorded when receiving billed products with fluctuating exchange rates. Specifically, it ensures exchange difference journal entries appear in the correct account when a negative exchange rate applies after a bill has been created. This ensures accurate financial reporting.
Original PR description
Issue ----- When receiving product after having billed it already, if: - the product is valuated, - the purchase is in a foreign currency, - there is an underlying exchange diff between time of bill…
Issue
-----
When receiving product after having billed it already, if:
- the product is valuated,
- the purchase is in a foreign currency,
- there is an underlying exchange diff between time of bill and reception
- the diff exchange rate is negative
then the exchange difference account move will occur in the regular exchange account.
Steps to reproduce
-----
- Enable automatic (anglo-saxon) accounting & dropshipping
- Enable the EUR currency and add 2 exchange rates
- today with 2:1 (EUR:USD)
- yesterday with 1:2 (EUR:USD)
- Create a new AVCO product category
- costing method: AVCO
- valuation: automatic
- Create a new product
- type: storable
- category: AVCO
- purchase: 5€
- set dropship route
- Create and confirm a SO
- Confirm PO and validate delivery
- Create bill for the PO
- change bill date to before yesterday & confirm
> Journal entry created in "Exchange Difference" journal
Cause
-----
Thanks to commit 80ff2d2 the flow is well behaved if the new rate is higher (company currency worth more comparatively) because we use the credit aml
https://github.com/odoo/odoo/blob/b57bb1decd46dcbb1fe602bb72b6f8e5382e9b28/addons/account/models/account_move_line.py#L2214-L2215
whose move has a svl
https://github.com/odoo/odoo/blob/b57bb1decd46dcbb1fe602bb72b6f8e5382e9b28/addons/stock_account/models/account_move.py#L335
This is not the case for the debit aml, so we end up using the default currency exchange account.
-----
Ticket:
opw-4797287