Daily updates from Odoo
Wednesday, June 10, 2026
323 changes
22 changes
Resolved issues and error corrections
This update resolves an issue where the 'Add to Cart' button wasn't functioning correctly for alternative products on the website. The fix ensures that users can successfully add these alternative products to their cart, improving the shopping experience. The change was made to correctly identify the button element within the website's product display.
Original PR description
Steps to reproduce: --- - Install `website_sale`. - Create a product and from the Sales tab, add alternative products, making sure all products are published on the website. - Open the main product…
Steps to reproduce: --- - Install `website_sale`. - Create a product and from the Sales tab, add alternative products, making sure all products are published on the website. - Open the main product on the website. - In the alternative products section, open the editor, click the `brush` icon under `card design`. - Under Actions > Buttons, click on the `cart` icon. - Save the changes and click the `Add to Cart` button on an alternative product. Issue: --- - Clicking the `Add to Cart` button on alternative products does nothing. Root cause: --- - At [1], the `AddToCart` interaction uses the selector `.oe_website_sale button[name="add_to_cart"]` to find and attach click handlers. When the dynamic snippet renders alternative products, `startInteractions` is called on the `.dynamic_snippet_template` div. It searches for the button inside that div, but at [2], no element wrapping the button has the `oe_website_sale` class in the rendered product card template. So the selector matches nothing, and no click handler is attached. Fix: --- - Add `oe_website_sale` to the `o_wsale_product_btn` wrapper div in the product card template so the button becomes a descendant of `.oe_website_sale` within the injected content, allowing the interaction to attach correctly. [1]https://github.com/odoo/odoo/blob/cbc446bfcaeeb4787cb512ddffbbeb2a154a6dde/addons/website_sale/static/src/interactions/add_to_cart.js#L5 [2]https://github.com/odoo/odoo/blob/cbc446bfcaeeb4787cb512ddffbbeb2a154a6dde/addons/website_sale/templates/snippets/product_snippet_template_data.xml#L95-L113 opw-6197375 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263253
This update ensures that descriptions are correctly populated on sales order lines when adding delivery items. Previously, only the product name was used, leading to incomplete order details. This fix maintains consistent and accurate product descriptions across all order stages, improving order clarity and reporting.
Original PR description
When a line is added to a delivery related to a sale order, the corresponding line created in the sale order uses only the display_name as a description. This commit makes sure that if a previous SO line exists for the product, the new line uses the same description. Otherwise we call `get_product_multiline_description_sale()` Steps to reproduce: - Create a product with a description in the Sales tab - Create a quotation with any product (can be said product) and confirm it - Go to the delivery action, and add a new line with the product in the view, set delivered quantity to 1 - After Validating, you'll notice that the new line in the Quotation doesn't have a description opw-6175891 Forward-Port-Of: odoo/odoo#267425 Forward-Port-Of: odoo/odoo#262276
This update enhances the SMS account registration process by adding clear error messages to the IAP system. Specifically, it now identifies issues like unsupported countries or inactive database records, providing better guidance to users. This improves the reliability and user experience of the SMS feature.
Original PR description
This commit add some error messages (country_not_supported, not_active_db) received by IAP. Task-6240200 IAP: https://github.com/odoo/iap-apps/pull/1612 Forward-Port-Of: odoo/odoo#267459
This update fixes an issue where the Balance Sheet report export was incorrectly including all accounts instead of the selected one when using the date filter. The fix removes a filtering process that was unintentionally introduced, ensuring the report accurately reflects the user's chosen account selection. This improves the reliability of financial reporting.
Original PR description
Steps: - Open Balance Sheet report and unfold lines - Open the General Ledger from a line with an account - On GL report, change date filter - Export XLSX report -> We export all accounts instead of the one selected in the search bar Cause: Since f8dceec74e44ffe4aef67655be8811c96da91eba we filter out the filter if a default account is defined in the context which is the case in the `caret_option_open_general_ledger` method Fix: Remove the filtering as the behavior that was fixed by the mentioned commit does not happen anymore. opw-6234427 Forward-Port-Of: odoo/enterprise#119588 Forward-Port-Of: odoo/enterprise#119156
This update resolves an issue where the database upgrade process would fail when reloading the Hungarian chart template due to a dependency on the NAV service. The fix bypasses the credential validation step during the migration, allowing upgrades to proceed smoothly without relying on external connectivity.
Original PR description
Steps to Reproduce: * Create a Hungarian company on 19.0 (or earlier). * Configure NAV credentials through Settings. * Upgrade the database to saas~19.2. Issue: * The upgrade fails while reloading…
Steps to Reproduce:
* Create a Hungarian company on 19.0 (or earlier).
* Configure NAV credentials through Settings.
* Upgrade the database to saas~19.2.
Issue:
* The upgrade fails while reloading the Hungarian chart template.
```python3
Traceback (most recent call last):
File "/home/odoo/src/odoo/saas-19.2/odoo/service/server.py", line 1626, in preload_registries
registry = Registry.new(dbname, update_module=update_module, install_modules=config['init'], upgrade_modules=config['update'], reinit_modules=config['reinit'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/tools/func.py", line 65, in locked
return func(inst, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/registry.py", line 202, in new
load_modules(
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/loading.py", line 502, in load_modules
migrations.migrate_module(package, 'end')
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/migration.py", line 215, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, version)
File "/home/odoo/src/odoo/saas-19.2/odoo/modules/migration.py", line 253, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_hu/migrations/3.1/end-migrate_update_taxes.py", line 7, in migrate
env['account.chart.template'].try_loading('hu', company)
File "/home/odoo/src/odoo/saas-19.2/addons/account/models/chart_template.py", line 181, in try_loading
return self._load(template_code, company, install_demo, force_create)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_hu_edi/models/template_hu.py", line 11, in _load
company._l10n_hu_edi_configure_company()
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_hu_edi/models/res_company.py", line 79, in _l10n_hu_edi_configure_company
res_config_id = self.env['res.config.settings'].create({
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/decorators.py", line 363, in create
return method(self, vals_list)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/hr_payroll/models/res_config_settings.py", line 39, in create
return super().create(vals_list)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/decorators.py", line 363, in create
return method(self, vals_list)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_hu_edi/models/res_config_settings.py", line 48, in create
record.company_id._l10n_hu_edi_test_credentials()
File "/home/odoo/src/odoo/saas-19.2/addons/l10n_hu_edi/models/res_company.py", line 107, in _l10n_hu_edi_test_credentials
raise UserError(
odoo.exceptions.UserError: Helytelen NAV hitelesítő adatok! Ellenőrizze, hogy a cég adószáma helyesen van-e beállítva.
Hiba részletei: HTTPSConnectionPool(host='api.onlineszamla.nav.gov.hu', port=443): Max retries exceeded with url: /invoiceService/v3/tokenExchange (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x798a970f1fd0>: Failed to establish a new connection: [Errno 111] Connection refused'))
```
Cause:
* Since the introduction of the Hungarian tax migration using `account.chart.template.try_loading('hu', company)` in saas~19.1, upgrades reload the Hungarian chart template.
* When `l10n_hu_edi` is installed, chart template loading triggers `_l10n_hu_edi_configure_company()`, which performs NAV credential validation through `_l10n_hu_edi_test_credentials()`.
* The credential validation performs a live request to the NAV service, making the upgrade dependent on an external service. https://github.com/odoo/odoo/blob/saas-19.2/addons/l10n_hu_edi/models/res_company.py#L99-L109 https://github.com/odoo/odoo/blob/saas-19.2/addons/l10n_hu_edi/models/template_hu.py#L11
Fix:
* Bypass NAV credential validation during the migration.
* The migration only updates localization data and does not modify the configured EDI credentials.
* This prevents temporary NAV connectivity issues from aborting the upgrade process.
see https://github.com/odoo/odoo/pull/253556
opw-6253523
upg-4326247
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#268178This update fixes a visual issue where the carousel display would become unstable when images were resized or changed. The update uses a new system to automatically adjust carousel item heights, ensuring a smooth and consistent user experience. This prevents layout problems and improves the overall appearance of the website builder.
Original PR description
In a carousel snippet all carousel items keep a consistent height to prevent layout jitter when sliding. The height synchronization was broken in the `s_carousel` snippet when item dimensions were modified via border overlays (padding changes). The issue was caused by the resize event being triggered from a different jQuery instance than the one used to register the height synchronization listener, preventing the handler from being executed. Steps to reproduce (Border Overlay): 1. In the website builder, add the `s_carousel` snippet. 2. Drag the lower border overlay so that the height of an image increases. 3. Navigate through the carousel and observe height changes causing a jitter effect. Task: [5135520](https://www.odoo.com/odoo/project/974/tasks/5135520) Forward-Port-Of: odoo/odoo#268722 Forward-Port-Of: odoo/odoo#265549
This update prevents a disruptive 'Access Error' in the command palette that appeared when users without accounting access attempted to use accounting report commands. The fix ensures that the system gracefully handles access restrictions, improving the user experience. It corrects a technical issue where the system incorrectly displayed an error message instead of simply not offering the command.
Original PR description
…n-accounting users Before this commit, users without accounting access rights would encounter an "Access Error" when typing in the command palette. This occurred because the 'account_report_variants' command provider was registered in the global namespace and unconditionally executed an RPC call to (get_available_variants) as soon as the user typed two or more characters. The backend ACLs correctly blocked this request, but resulted in a disruptive error dialog for the user. This commit fixes the issue by verifying that the user has access to the accounting reports or the acounting app, if they don't it would return an empty list. Steps to reproduce the bug: 1. Log in as admin 2. Go to the Users view 3. Set ESG to 'No' 4. Set Accounting to 'No' 5. Refresh the page 6. Open and use the command palette -> Access Error: You are not allowed to access 'Accounting Report' records. task: 6246337 m
This update ensures that fiscal category and product information is automatically loaded when using the self-order blackbox feature. Previously, this data wasn't consistently available, leading to potential inaccuracies. This change improves the reliability and accuracy of self-order transactions.
Original PR description
Before this commit, the fiscal category and the products work in and work out weren't necessarily automatically loaded when using the self with a blackbox, it is now the case. Forward-Port-Of: odoo/enterprise#117288 Forward-Port-Of: odoo/enterprise#117044
This update fixes an issue where self-order receipts incorrectly displayed 'Service at Table' instead of 'Pickup At Counter' when a customer selected a counter service without identification. This change ensures the receipt accurately reflects the customer's order method, improving clarity and accuracy for both staff and customers. The fix was implemented as part of the standard Odoo development process.
Original PR description
When selecting a preset with a service at counter but without identification, after a self order the receipt header was wrongly showing "Service at Table" instead of "Pickup At Counter". This is now fixed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264454 Forward-Port-Of: odoo/odoo#264115
This update fixes an issue where Point of Sale account move lines were incorrectly reporting tax base amounts as always positive, regardless of the sale's actual tax impact. This change ensures that tax calculations in POS transactions accurately reflect the tax liability, leading to more precise accounting reports. It resolves a discrepancy in how tax amounts were processed.
Original PR description
Issue: While creating an account move line from POS, the tax_base_amount of tax line is always positive although it might be negative. Steps to reproduce: - with point_of_sale and account_reports - open register - Sale a product with taxes - close register - Go to Accounting -> Tax Report - Switch to current month - On a line click on the tree dots -> Audit Current Behavior: - POS AMLs always have a positive tax base amount for tax lines. Expected behavior: - POS AMLs have a positive or negative base amount for tax lines depending on the move. opw-5975658 Forward-Port-Of: odoo/odoo#265479
This update fixes an issue where untaxed invoice lines were incorrectly inheriting datev code from the previous line in the report. This resulted in inaccurate datev reports, particularly for German companies. The fix ensures that untaxed lines now correctly have an empty datev code, aligning with the expected report format.
Original PR description
**PROBLEM** Untaxed move lines would take the datev code of the previous line instead of having no datev code like they should. **STEP TO REPRODUCE** 1. On a german company, create an invoice with a line with tax 19% I, and a line that is untaxed (with a non-null price). 2. On the general ledger, generate the datev zip. 3. Unzip, and open the account entries csv, and notice the 2nd line of the invoice as the datev code set to something instead of it being empty (column BU-Schlüssel). opw-6141003 Forward-Port-Of: odoo/enterprise#118486
This update resolves an issue where invoices for Persona Natura customers in Colombia were incorrectly formatted for export to the DIAN tax authority. The fix ensures the correct XML structure is generated, addressing a misinterpretation of customer types and preventing export errors. This ensures accurate tax reporting for Colombian businesses.
Original PR description
Issue: Colombian partner being Persona Natura are misinterpreted as Person Juridica. It raises issue while exporting XMLs for dian. Steps to reproduce: - In a Colombian company - Create a Customer with NIT and "Obligaciones y Responsabilidades" to "R-99-PN" - Create an invoice - Send the invoice Current behavior: - node <cbc:AdditionalAccountID> is set to 1 and node PartyIdentification is missing Expected behavior: - node <cbc:AdditionalAccountID> is set to 2 and there is a PartyIdentification node Cause: Colombian partners having a NIT have is_company to True. However, Persona Natura have NIT but aren't companies. opw-6206308 Forward-Port-Of: odoo/enterprise#118193
This update resolves an error that occurred during DHL delivery confirmations when the scheduled delivery date was missing or set to a past time. The system now automatically sets the delivery date to one hour in the future, preventing the error and ensuring successful order confirmations.
Original PR description
When confirming the delivery of an order using DHL shipping method we get an error that the date must be in the future. This happens when the scheduled date was not set, or set for a time in the past. This commit automatically sets the time to 1 hour in the future and bypasses the user error. opw-6148927 Forward-Port-Of: odoo/enterprise#116211
This update fixes an issue where the 'Cancel Reason' wasn't properly transmitted when reversing invoices in Peruvian companies. Now, the credit note generated for the reversal accurately includes the user-specified cancellation reason, ensuring compliance with Peruvian tax regulations (SUNAT) and providing complete documentation.
Original PR description
### Issue before this commit: When reversing an invoice in a Peruvian company, the "Cancel Reason" entered in the credit note window is not propagated to the Peruvian EDI tab of the resulting Credit…
### Issue before this commit: When reversing an invoice in a Peruvian company, the "Cancel Reason" entered in the credit note window is not propagated to the Peruvian EDI tab of the resulting Credit Note. Only the Credit Reason is successfully reported. ### Steps to reproduce the issue: 1. Download Accounting and l10n_pe 2. Switch to PE company 3. Create an invoice and confirm it 4. Create a credit note for the invoice with a cancel reason and a credit reason and click the reverse button 5. See that in the Peruvian EDI tab only the Credit Reason is reported but not the Cancel Reason ### Cause of the issue: In the l10n_pe_edi module, the override of the _prepare_default_reversal method maps the l10n_pe_edi_refund_reason to the new move's values, but completely omits the mapping of the wizard's textual reason field to the l10n_pe_edi_cancel_reason field of the resulting credit note. ### Reason to introduce the fix: To ensure the generated credit notes contain all required information for the Peruvian EDI (SUNAT). Mapping the cancel reason guarantees that the electronic document accurately reflects both the refund code and the descriptive cancellation text provided by the user. opw-6238525 Forward-Port-Of: odoo/enterprise#119610 Forward-Port-Of: odoo/enterprise#118479
This update fixes an issue where grouped payments were incorrectly linking to unrelated invoices after reconciliation. The process has been updated to ensure payments are accurately associated with the invoices they cover, preventing duplicate payment entries. This improves the accuracy of financial reporting.
Original PR description
Steps to reproduce --- 1. Register a grouped customer payment over several invoices, leaving one of them only partially paid. 2. Register a second grouped payment over two invoices: the partially…
Steps to reproduce --- 1. Register a grouped customer payment over several invoices, leaving one of them only partially paid. 2. Register a second grouped payment over two invoices: the partially paid one and a brand new invoice. 3. Open the first payment, its "Reconciled Invoices" smart button now lists the new invoice from the second payment, which it never paid. Issue --- The smart button is built from the stored `invoice_ids` many2many, which shares its relation table with `account.move.matched_payment_ids`. After reconciling, the register wizard links the payment to its invoices with `lines.move_id.matched_payment_ids += payment` at https://github.com/odoo/odoo/blob/f726393267a28cedd5febd2106de17ae3838f3ff/addons/account/wizard/account_payment_register.py#L1212. When the payment groups several invoices, `lines.move_id` is a multi-record recordset. Reading `matched_payment_ids` on it returns the union of the payments already linked to all those invoices, and `+=` writes that union back to every invoice as a `(6, 0, ...)` replace command. So an invoice already paid by an earlier payment spreads that earlier payment onto every other invoice grouped in the new one, including brand new invoices, which then wrongly appear on the earlier payment. opw-6188013 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267968
This update removes a specific message from invoices sent outside of PEPPOL, which was inappropriate for Business-to-Consumer (B2C) customers. The change ensures that B2C invoices are cleaner and more professional, aligning with customer expectations. This fix was implemented to improve the user experience for B2C transactions.
Original PR description
Currently, if the invoice was not sent through PEPPOL, it is indicated in the mail footer. However, this message is not appropriate for B2C customers. To avoid this, we remove this footer for customers with empty or '/' VAT (B2C). task-6167439 Forward-Port-Of: odoo/odoo#269094 Forward-Port-Of: odoo/odoo#262412
This update corrects a bug where order filters on the Ticket Screen in Point of Sale weren't updating correctly when a different provider state was selected. The fix forces a reload of the Ticket Screen, ensuring that the displayed orders reflect the current state and filters. This prevents outdated order information from being shown to users.
Original PR description
Steps to Reproduce ------------------------- - Install Point of Sale and configure UrbanPiper. - Open a POS session and select a provider state from the notification popup to review orders. - While on the Ticket Screen, select a different provider state to review other orders. Issue ------- - Orders are not updated according to the newly selected state. - Previously applied filters remain unchanged. Cause -------- - Since the user is already on the Ticket Screen, changing only the provider state does not trigger a re-render. - The page was already rendered with the old filters. Fix ---- - The Ticket Screen is first switched away and then re-rendered. - This forces the screen to reload with the updated state and filters. Task: 6079663 Forward-Port-Of: odoo/enterprise#119828 Forward-Port-Of: odoo/enterprise#104546
This update ensures that DATEV customer and supplier export files accurately reflect customer information for non-EU countries like Switzerland. Previously, incorrect fields were populated, but this fix now correctly uses the 'Land' field for these customers, aligning with DATEV's data format requirements and preventing errors in reporting.
Original PR description
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries…
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries For non-EU countries, the `Land` field should be filled instead, and is required whenever the country is not Germany https://developer.datev.de/en/file-format/details/datev-format/format-description/debitorskreditors ### Cause: `_l10n_de_datev_get_partner_list` did not distinguish between EU and non-EU countries As a result, any partner with a VAT number could populate `EU-Land` and `EU-UStID`, even if the country was outside the EU Greece also requires a special case: its VAT prefix is `EL` so the `EU-Land` too, while the country code used in `Land` must remain `GR` ### Steps to reproduce: - Install `l10n_de_reports` and switch to the DE company - Create a customer in Switzerland with a valid VAT number - Create and confirm an invoice for that customer - Go to Accounting → Audit Reports → General Ledger - Select the full year - From the gear menu, export DATEV DATA (zip) - Open the `EXTF_customer_accounts` file ### Before the fix: `EU-Land` and `EU-UStID` are filled for the Swiss customer, while `Land` is empty ### After the fix: `EU-Land` and `EU-UStID` are empty for non-EU countries such as Switzerland, while `Land` is correctly filled `Land` is filled using the following priority: 1. Partner country_code 2. Country extracted from the VAT number 3. Empty opw-5902565 Forward-Port-Of: odoo/enterprise#119780 Forward-Port-Of: odoo/enterprise#113835
This update resolves an issue preventing users in Peru from generating Closing Entries within the tax reporting feature. The fix creates a specific tax report variant for Peru, ensuring accurate VAT calculations and restoring the automated closing account configuration process. This improves the reliability of financial reporting for Peruvian businesses.
Original PR description
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that…
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that you need a Return Type in order to make a Closing Entry using the Validate button Additionally, using the Generic Tax Report by default creates a risk in Multi-VAT environments, as it mixes taxes from all countries instead of isolating Peruvian taxes ### Cause The new 18.3 accounting workflow requires at least one active Return Type associated with a country-specific report variant to display the Return options and process the closing entry Peru was relying on the Generic Tax Report, without a dedicated report variant No Return Type was configured, which blocked Odoo's automatic VAT closing workflow and prevented the system from prompting the user to configure the required closing accounts ### Steps to reproduce - Install `l10n_pe_reports` and `accountant` - Switch to a PE Company - Go to the Tax Report Before the fix, no Returns button is available for any of the existing reports, making it impossible to use Odoo's automatic process to configure the tax accounts and trigger the closing entry ### Notes This is fixed by creating a dedicated Peruvian tax report variant directly in Enterprise that inherits from the generic tax report A custom handler is added to force the domain filtering on Peruvian taxes only, and a corresponding Return Type is defined to restore the full closing entry process safely opw-5978673 Forward-Port-Of: odoo/enterprise#117891
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must precede the end time for a valid shift template. This ensures users receive clear and helpful guidance.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
This update resolves a crash in the payslip PDF report that occurred when employees didn't have a bank account configured. The fix adds a simple check to ensure the bank account section is only displayed if an employee actually has a linked bank account, improving report stability and preventing errors.
Original PR description
The payslip PDF report crashed when the employee had no bank account configured because the template tried to access bank_account_ids[0] unconditionally. Add a t-if guard on the bank account div to only render it when the employee has at least one bank account linked. Forward-Port-Of: odoo/enterprise#115893
Previously, a sign request scheduled for the future would immediately show up on the portal for the signer. This fix corrects a technical issue where the system wasn't properly recognizing scheduled requests. Now, scheduled requests will only appear on the portal after the scheduled date, ensuring a smoother user experience.
Original PR description
## Issue When scheduling a sign request, the request appears immediately on the portal for the requested signer. ## Steps to reproduce 1. Install *Sign* (`sign`) 2. Create and send a sign request -…
## Issue
When scheduling a sign request, the request appears immediately on the portal for the requested signer.
## Steps to reproduce
1. Install *Sign* (`sign`)
2. Create and send a sign request
- Signer 1: Any portal user (e.g., Joel Willis)
- Use the clock icon to schedule the signature request to a future date
3. Log in as the portal user used in step 2
4. Navigate to Signature Requests
5. **The signature request already appears in the list, even though it was scheduled for a future date.**
## Cause
The portal filters the sign requests shown based on the `is_mail_sent` field, which does not properly reflect when the signature request is shared to the user.
https://github.com/odoo/enterprise/blob/9898272f17809decf6c5bb4600aca46f9ffae6f0/sign/controllers/portal.py#L40
In fact, when scheduling a signature request, the `is_mail_sent` field is unconditionally set to `True`, even if the signature request will only be sent later.
https://github.com/odoo/enterprise/blob/9898272f17809decf6c5bb4600aca46f9ffae6f0/sign/models/sign_request_item.py#L289
## Fix
Since the `"scheduled"` `sign_request_item.state` option introduced by https://github.com/odoo/enterprise/commit/ed8d5a653e01b1378f0020e2f7a7c2d39fadf3e9 in 19.1, we can easily filter out the sign request items that are scheduled. That state is automatically updated by the `_cron_update_state`, introduced by the same commit as the `"scheduled"` option.
https://github.com/odoo/enterprise/blob/9898272f17809decf6c5bb4600aca46f9ffae6f0/sign/models/sign_request.py#L493-L503
opw-6227472
Forward-Port-Of: odoo/enterprise#11849110 changes
Enhancements to existing features
This update improves the D300 VAT report for Romanian businesses. The report's name has been changed to better align with local regulations and reporting requirements. This ensures accurate and compliant financial reporting for Odoo users in Romania.
Original PR description
Rename VAT report fom Romania task-5423935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252511
This update improves the Romanian VAT reporting process within Odoo Enterprise. It renames the VAT report and generates an XML file, aligning with the latest requirements set by the Romanian tax authority (ANAF). This ensures accurate and compliant D300 returns.
Original PR description
Rename VAT report fom Romania and generate XML file to complete flow for D300 return complying with the latest ANAF specifications. https://static.anaf.ro/static/10/Anaf/Declaratii_R/300.html task-5423935 Forward-Port-Of: odoo/enterprise#109849
Resolved issues and error corrections
This update resolves an issue where the system previously restricted searches using record IDs to only positive numbers. During database migrations, negative IDs could occur. This change allows the system to correctly handle negative IDs, ensuring broader record search capabilities. This improves data accessibility and reliability.
Original PR description
Currently, the validation for the name_service only allows us to search on records with ids greater than or equal to one but in some edge cases like migrations where databases needed to be merged, we ended up with negative ids (v6.0 migration on odoo.com). The ORM is capable of handling these so we allow it in the name_service as well. opw-6213802
This update fixes an issue where DATEV export files incorrectly included EU-specific fields for customers outside the European Union. The change ensures that the correct country code (`Land`) is used for non-EU partners, aligning with DATEV's data format requirements and preventing inaccurate reporting. This improves data consistency and compliance.
Original PR description
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries…
### Issue: In DATEV customer and supplier exports, partners outside the European Union still had the `EU-Land` and `EU-UStID` fields filled However, these fields must only be used for EU countries For non-EU countries, the `Land` field should be filled instead, and is required whenever the country is not Germany https://developer.datev.de/en/file-format/details/datev-format/format-description/debitorskreditors ### Cause: `_l10n_de_datev_get_partner_list` did not distinguish between EU and non-EU countries As a result, any partner with a VAT number could populate `EU-Land` and `EU-UStID`, even if the country was outside the EU Greece also requires a special case: its VAT prefix is `EL` so the `EU-Land` too, while the country code used in `Land` must remain `GR` ### Steps to reproduce: - Install `l10n_de_reports` and switch to the DE company - Create a customer in Switzerland with a valid VAT number - Create and confirm an invoice for that customer - Go to Accounting → Audit Reports → General Ledger - Select the full year - From the gear menu, export DATEV DATA (zip) - Open the `EXTF_customer_accounts` file ### Before the fix: `EU-Land` and `EU-UStID` are filled for the Swiss customer, while `Land` is empty ### After the fix: `EU-Land` and `EU-UStID` are empty for non-EU countries such as Switzerland, while `Land` is correctly filled `Land` is filled using the following priority: 1. Partner country_code 2. Country extracted from the VAT number 3. Empty opw-5902565 Forward-Port-Of: odoo/enterprise#119780 Forward-Port-Of: odoo/enterprise#113835
This update resolves an issue preventing users in Peru from generating closing entries for their tax reports. The fix introduces a dedicated Peruvian tax report variant, ensuring accurate VAT calculations and restoring the automated closing account configuration process. This improves the reliability of the Peruvian accounting workflow.
Original PR description
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that…
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that you need a Return Type in order to make a Closing Entry using the Validate button Additionally, using the Generic Tax Report by default creates a risk in Multi-VAT environments, as it mixes taxes from all countries instead of isolating Peruvian taxes ### Cause The new 18.3 accounting workflow requires at least one active Return Type associated with a country-specific report variant to display the Return options and process the closing entry Peru was relying on the Generic Tax Report, without a dedicated report variant No Return Type was configured, which blocked Odoo's automatic VAT closing workflow and prevented the system from prompting the user to configure the required closing accounts ### Steps to reproduce - Install `l10n_pe_reports` and `accountant` - Switch to a PE Company - Go to the Tax Report Before the fix, no Returns button is available for any of the existing reports, making it impossible to use Odoo's automatic process to configure the tax accounts and trigger the closing entry ### Notes This is fixed by creating a dedicated Peruvian tax report variant directly in Enterprise that inherits from the generic tax report A custom handler is added to force the domain filtering on Peruvian taxes only, and a corresponding Return Type is defined to restore the full closing entry process safely opw-5978673 Forward-Port-Of: odoo/enterprise#117891
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must precede the end time, ensuring correct shift template creation. This improves usability for users.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
This fix resolves an issue where credit notes for returned dropshipped products incorrectly displayed the wrong lot number on invoices. The update ensures that the correct lot number (the returned one) is shown, improving accuracy and transparency in financial reporting for dropshipping transactions.
Original PR description
**Issue** Printing a credit note for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report. **Steps to reproduce** - Activate "Display Lots & Serial…
**Issue**
Printing a credit note for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report.
**Steps to reproduce**
- Activate "Display Lots & Serial Numbers on Invoices"
- Create a product tracked by serial/lot and enable the dropship route
- Create two lots: "lot1" and "lot2"
- Create and confirm a SO for quantity 2
- Confirm the PO and validate the dropship for both lots
- Create and post an invoice
- Return "lot2" from the dropship picking
- Create and post a credit note for quantity 1
- Click on print -> The generated PDF displays "lot1" instead of "lot2"
**Cause**
While rendering `account.report_invoice_with_payments`, the report calls `_get_invoiced_lot_values` to determine which lot/serial numbers should be displayed:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L31-L32 `invoiced_qties = 1` since the credit is on a quantity of 1 https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L44 Three stock move lines are retrieved from the SO:
- the two original dropship deliveries,
- the return move for `lot2`. https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L63 However, none of them are considered as `is_stock_return` because the dropship locations use `supplier` instead of `internal`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L72-L76 As a consequence:
- The two original delivery move lines each keep quantity `1`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L69 they never pass through the return handling logic: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L77-L80 which would make it as -1 (since `qties_per_lot[sml.lot_id]` is 0 for the first iteration of `sml.lot_id`). Thus, it does not pass by this code (since quantity is greater than 0): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L87-L90 which would make it as 0.
- for the last one, `is_stock_return = False` as it should be, thus the quantity is 1 as it should be. The quantities are therefore accumulated as:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L92
resulting in:
`qties_per_lot = {lot1: 1, lot2: 2}`
instead of:
`qties_per_lot = {lot1: 0, lot2: 1}`
The report then selects the first matching lot and stops: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L94-L99
opw-6230281
Forward-Port-Of: odoo/odoo#266716A test was failing due to a minor issue with how content snippets were dropped into a website feature. This update corrects the placement logic, ensuring snippets are reliably added to the intended location, preventing test failures. This improves the stability and reliability of the website content editor.
Original PR description
Test that was testing that we cannot drop some snippets in a table of content sometimes failed due to the fact that it could sometimes drop in the wrong drop zone. This happens because 2 dropzones are really close to each other: <--- dropzone ---> [1] <--- toc start ---> <--- dropzone ---> [2] <--- section ---> <--- dropzone ---> [3] ... <--- toc end ---> When we move the snippet thumbnail to the dropzone [2], and drop it by calling `getDragHelper` it recomputes the position of the thumbnail, and sometimes it may drop the snippet in the first dropzone [1], breaking the test flow. We fix it by moving the snippet to the third dropzone [3], where it surely will drop, as there are no neighboring dropzones. runbot-241922 Forward-Port-Of: odoo/odoo#268473
This update resolves an issue where employees with overlapping contracts would incorrectly receive a 'Duplicate Payslip' warning. The change limits the warning check to only consider payslips with the same version, ensuring more accurate payroll processing. This improves the user experience and prevents unnecessary alerts.
Original PR description
If an employee has a contract that ends in the middle of the month and another contract starts in the same month, the two payslips that are created for the month trigger the "Duplicate Payslip" warning, even though they use different version IDs. This commit limits the search domain for the duplicate payslips to only consider payslips with the same version ID. task-6226391 Forward-Port-Of: odoo/enterprise#118652
This update resolves a performance issue that caused significant lag when hovering over account reports with many columns. The change optimizes CSS styling to reduce unnecessary calculations, resulting in a smoother and faster user experience. This improves the responsiveness of a key business reporting tool.
Original PR description
Forward-Port-Of: odoo/enterprise#119242
10 changes
Enhancements to existing features
This update improves the D300 VAT report for Romanian businesses. The report's name has been changed to better align with local regulations and reporting requirements. This ensures accurate and compliant financial reporting for Odoo users in Romania.
Original PR description
Rename VAT report fom Romania task-5423935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252511
This update improves the generation of the D300 VAT report for Romania, aligning with the latest requirements from the ANAF (Romanian tax authority). It now creates an XML file, completing the necessary flow for submitting the report, ensuring compliance and accurate tax reporting.
Original PR description
Rename VAT report fom Romania and generate XML file to complete flow for D300 return complying with the latest ANAF specifications. https://static.anaf.ro/static/10/Anaf/Declaratii_R/300.html task-5423935 Forward-Port-Of: odoo/enterprise#109849
Resolved issues and error corrections
This update corrects a discrepancy in product pricing across Odoo. Previously, changing the price on a product's variant form didn't update the main product template. Now, the system ensures that the sales price is consistently reflected across both the product variant and the main product template, improving data accuracy for sales and inventory management.
Original PR description
Issue: When the sales price is changed from the product variant form for a product without configured variants, the price is updated only on `product.product.lst_price`. The main product form, opened…
Issue: When the sales price is changed from the product variant form for a product without configured variants, the price is updated only on `product.product.lst_price`. The main product form, opened from Inventory > Products, displays `product.template.list_price`, which remains unchanged. The same issue is visible from Purchase Orders because the product internal link on a purchase order line opens `product.product`, while the product page opens `product.template`. Steps to reproduce: - Create or open a product without configured variants - Open product variant form from the internal link in a purchase order - Change the Sales Price on the product from there - Open the product from Inventory > Products (`product.template`) - The template Sales Price still shows the old value Cause: Since version 19.1, `product.product.lst_price` is an editable stored field, allowing variant-level prices to differ from the template price. This is correct for products with multiple variants, where each variant may have its own sales price. However, for products with only one variant (the product itself), no synchronization was performed from `product.product.lst_price` back to `product.template.list_price`, leaving both product forms inconsistent. Solution: - Add `_inverse_product_lst_price` on `product.product.lst_price` so that When `lst_price` is written and the template has exactly one variant, set `list_price` to `lst_price` (delegates to the template) opw-6260015 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update significantly improves the speed of syncing participants to marketing campaigns, particularly for large campaigns. By optimizing the underlying code, the process now takes just a fraction of the previous time (from 51.71 seconds to 0.652 seconds). This enhancement ensures smoother campaign management and reduces potential delays for users.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#119589 Forward-Port-Of: odoo/enterprise#117656
This update fixes an issue where delivery orders weren't correctly reserving newly produced lots in multi-step manufacturing workflows. Specifically, changing the destination of a 'Store Finished Products' transfer to a sublocation within the warehouse caused the system to incorrectly break the MTO link. Now, the delivery order will always reserve the intended, freshly produced lot.
Original PR description
Steps to reproduce: - Create a storable product “P1” with Lot tracking - Enable routes: MTO + Manufacture - Create a BoM for the product: - Component: C1 - Configure the warehouse with 3-step…
Steps to reproduce:
- Create a storable product “P1” with Lot tracking
- Enable routes: MTO + Manufacture
- Create a BoM for the product:
- Component: C1
- Configure the warehouse with 3-step manufacturing
- Have on-hand stock in WH/Stock with Lot 001
- Confirm a Sales Order for the product
- Confirm the generated Manufacturing Order and produce Lot 002
- In the "Store Finished Products" transfer, change the destination location from WH/Stock to WH/Stock/Shelf 1 and validate
- Check the Delivery Order reservation
Problem:
The move is reserved with Lot 001 instead of 002
When using a 3-step manufacturing flow (MTO + Manufacture), if the user manually changes the destination of the "Store Finished Products" transfer to a sublocation of WH/Stock (e.g. WH/Stock/Shelf 1), the MTO link between the production and the delivery order was incorrectly broken, causing the delivery to reserve existing stock instead of the freshly produced lot.
Root cause: `_skip_push()` only skipped push logic when the downstream move's source was a child-or-equal of the current move's destination (`m.location_id._child_of(self.location_dest_id)`). When the destination was changed to a sublocation (WH/Stock/Shelf 1), this check failed, so `_push_apply()` ran, found the delivery's source (WH/Stock) was not a child of WH/Stock/Shelf 1, and called `_break_mto_link()`, clearing `move_orig_ids` on the delivery move. The delivery then fell back to make-to-stock reservation and picked an unrelated lot.
opw-6197212
Forward-Port-Of: odoo/odoo#268783This update resolves an issue where Peruvian tax reports couldn't generate closing entries due to a change in Odoo's accounting workflow. The fix creates a specific report variant for Peru, ensuring accurate tax calculations and restoring the automatic closing entry process for Peruvian businesses.
Original PR description
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that…
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that you need a Return Type in order to make a Closing Entry using the Validate button Additionally, using the Generic Tax Report by default creates a risk in Multi-VAT environments, as it mixes taxes from all countries instead of isolating Peruvian taxes ### Cause The new 18.3 accounting workflow requires at least one active Return Type associated with a country-specific report variant to display the Return options and process the closing entry Peru was relying on the Generic Tax Report, without a dedicated report variant No Return Type was configured, which blocked Odoo's automatic VAT closing workflow and prevented the system from prompting the user to configure the required closing accounts ### Steps to reproduce - Install `l10n_pe_reports` and `accountant` - Switch to a PE Company - Go to the Tax Report Before the fix, no Returns button is available for any of the existing reports, making it impossible to use Odoo's automatic process to configure the tax accounts and trigger the closing entry ### Notes This is fixed by creating a dedicated Peruvian tax report variant directly in Enterprise that inherits from the generic tax report A custom handler is added to force the domain filtering on Peruvian taxes only, and a corresponding Return Type is defined to restore the full closing entry process safely opw-5978673 Forward-Port-Of: odoo/enterprise#117891
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must precede the end time, improving usability for users creating shift templates. This ensures accurate shift scheduling.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
A recent test failed due to a minor issue with how content snippets were being dropped onto the website builder. This update corrects a positioning problem within the test environment, ensuring snippets are reliably placed in the intended location. This resolves a technical bug that didn't directly impact users.
Original PR description
Test that was testing that we cannot drop some snippets in a table of content sometimes failed due to the fact that it could sometimes drop in the wrong drop zone. This happens because 2 dropzones are really close to each other: <--- dropzone ---> [1] <--- toc start ---> <--- dropzone ---> [2] <--- section ---> <--- dropzone ---> [3] ... <--- toc end ---> When we move the snippet thumbnail to the dropzone [2], and drop it by calling `getDragHelper` it recomputes the position of the thumbnail, and sometimes it may drop the snippet in the first dropzone [1], breaking the test flow. We fix it by moving the snippet to the third dropzone [3], where it surely will drop, as there are no neighboring dropzones. runbot-241922 Forward-Port-Of: odoo/odoo#268473
This update clarifies the reporting of employee hours by renaming a confusing column from "Expected Hours" and "Theoretical Hours" to "regular hours". Previously, the column didn't accurately represent the employee's contracted work hours, leading to potential misinterpretations. This change ensures reporting aligns with the intended measure of actual work hours.
Original PR description
The column name "Expected Hours" and "Theoretical Hours" is confusing since it doesn't show the hours that the employee is supposed to work according to their contract, just the number of hours that are not considered overtime. This commit renames the column to better reflect the measure that is shown. task-6123642 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#262230
This update fixes a problem where receipt printing in Austria was incorrect, and prevented a deadlock during authentication with Fiskaly and FON. The changes ensure accurate receipt closing and a smoother authentication process for users in Austria, improving the overall POS experience.
Original PR description
In this task: -------------- - Fixed Austria closing receipt printing by calculating the offset from the last closed month instead of the current month. Closing records are returned in ascending order and exist only for completed months, so the latest month must use offset 0. - Prevent a deadlock during Fiskaly and FON authentication by checking for open sessions before starting any authentication flow, instead of after the first step of authentication. - The resp was used to show error which was not in the scope. task: 5420256 Forward-Port-Of: odoo/enterprise#119454 Forward-Port-Of: odoo/enterprise#102313
5 changes
Enhancements to existing features
This update enhances the synchronization of financial transactions with Fiskaly for both retail and restaurant orders. It streamlines the process by sending complete transaction data only upon order validation, improving efficiency and data accuracy. This change ensures seamless integration with Fiskaly's reporting system.
Original PR description
In this commit: ------------------ - Maintain separate Fiskaly transaction flows for retail (short tx) and restaurant (long tx) orders as discussed with the Fiskaly team. - `Initialize order…
In this commit: ------------------ - Maintain separate Fiskaly transaction flows for retail (short tx) and restaurant (long tx) orders as discussed with the Fiskaly team. - `Initialize order transactions` with an empty payload when the `first product` is added. - Start `receipt transactions` with an empty payload when the `first payment line` is added. - For retail flows, no intermediate order updates are sent to Fiskaly before finalization. - For restaurant flows, create additional transaction updates during kitchen synchronization. Ensure already synchronized products are not resent, and only newly added or updated quantities are included in the payload. - `Finalize order and receipt transactions` with complete order lines and payment details when we validate the order. task: 6208963 Reference: <img width="1863" height="1285" alt="de_tss_flow" src="https://github.com/user-attachments/assets/9140788e-7948-4a08-9f11-27197b22ca8b" /> Forward-Port-Of: odoo/enterprise#119765 Forward-Port-Of: odoo/enterprise#117526
Resolved issues and error corrections
This update fixes an issue where subscription product quantities weren't correctly applying pricelist rules, specifically when the quantity was set to 1. The change ensures that the unit price adjusts to the correct price based on the defined quantity tiers, improving the accuracy of subscription billing.
Original PR description
Steps to produce: --- - Install `sale_subscription` module. - Enable `pricelists` from Settings. - Create a new subscription product. - Create a new pricelist and Under Recurring Prices, add below…
Steps to produce:
---
- Install `sale_subscription` module.
- Enable `pricelists` from Settings.
- Create a new subscription product.
- Create a new pricelist and Under Recurring Prices, add below rules for
the monthly recurring plan on creatred subscription product:
- Min Qty = 0 then Price = 0.
- Min Qty = 10 then Price = 10.
- Min Qty = 20 then price = 20.
(This setup ensures the product is free when the quantity is less than 10, and
pricing increases based on the defined quantity tiers.)
- Create a sale order > Set a customer > Select the recurring plan as `Monthly` > Apply the created pricelist.
- Add the subscription product with quantity = 20 then Unit price is correctly set to 20.
- Change the quantity to 1.
Observation:
---
- The unit price does not update to 0 as expected.
Root cause:
---
- At [1], when quantity is updated to 1, `super()._get_pricelist_price()` correctly returns `0`.
- However, due to the `or self.price_unit` condition, the existing unit price is retained instead of applying the new value.
- This prevents valid pricelist rules (including zero-priced ones) from being applied.
Fix:
---
- As shown in [2], `line.pricelist_item_id` is set when a matching pricelist rule is found. Therefore, when a rule (including one for quantity = 0) applies, it will be reflected in `line.pricelist_item_id`.
- If `pricelist_item_id` is set, the computed price from the rule must be used; otherwise, fall back to the existing unit price.
[1]: https://github.com/odoo/enterprise/blob/7498010b8206df56fc5d8a9fd08b24169bf08cb2/sale_subscription/models/sale_order_line.py#L651-L654
[2]: https://github.com/odoo/odoo/blob/fab39bbea642c1a185e6cb91afea860fa0c0f27d/addons/sale/models/sale_order_line.py#L547-L557
opw-6122234
---This update significantly speeds up the process of adding and removing participants from marketing campaigns. The change optimizes a key function within the marketing automation module, reducing processing time from over 51 seconds to just 0.65 seconds when handling large campaigns (over 115,000 participants). This improves overall campaign management efficiency.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#119589 Forward-Port-Of: odoo/enterprise#117656
This update resolves an issue where PE tax reports in Odoo 18.4 couldn't generate closing entries due to a change in the accounting workflow. The fix adds a dedicated Peruvian tax report variant and a Return Type, allowing users to correctly configure tax accounts and trigger the closing process safely, particularly in multi-VAT environments.
Original PR description
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that…
### Issue Since the introduction of the Tax Returns feature in 18.3, it was no longer possible to generate a Closing Entry as the button has been replaced by Returns The Return mechanism implies that you need a Return Type in order to make a Closing Entry using the Validate button Additionally, using the Generic Tax Report by default creates a risk in Multi-VAT environments, as it mixes taxes from all countries instead of isolating Peruvian taxes ### Cause The new 18.3 accounting workflow requires at least one active Return Type associated with a country-specific report variant to display the Return options and process the closing entry Peru was relying on the Generic Tax Report, without a dedicated report variant No Return Type was configured, which blocked Odoo's automatic VAT closing workflow and prevented the system from prompting the user to configure the required closing accounts ### Steps to reproduce - Install `l10n_pe_reports` and `accountant` - Switch to a PE Company - Go to the Tax Report Before the fix, no Returns button is available for any of the existing reports, making it impossible to use Odoo's automatic process to configure the tax accounts and trigger the closing entry ### Notes This is fixed by creating a dedicated Peruvian tax report variant directly in Enterprise that inherits from the generic tax report A custom handler is added to force the domain filtering on Peruvian taxes only, and a corresponding Return Type is defined to restore the full closing entry process safely opw-5978673 Forward-Port-Of: odoo/enterprise#117891
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must be before the end time, improving clarity for users creating shift templates. This ensures accurate shift scheduling.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
6 changes
Resolved issues and error corrections
This update fixes a display issue where time off allocation titles showed excessively long decimal numbers. The change rounds the calculated duration to two decimal places, presenting a cleaner and more user-friendly view of the requested time off. This ensures accurate and easily understandable information for employees and managers.
Original PR description
Steps to reproduce: ------------------- 1. Install Time Off 2. Create an employee with a 38-hour working schedule (7.6h/day) 3. Create a time off type with request unit set to "Hours" 4. Create an…
Steps to reproduce: ------------------- 1. Install Time Off 2. Create an employee with a 38-hour working schedule (7.6h/day) 3. Create a time off type with request unit set to "Hours" 4. Create an allocation for this employee with a duration of 8 hours 5. Observe the allocation title displaying a long decimal value. (e.g., 7.999999999999999) Issue: ------ The `number_of_days` is calculated in `_compute_number_of_days` using: https://github.com/odoo/odoo/blob/ca01e606928a7704c6b2e4f430710f895be2653d/addons/hr_holidays/models/hr_leave_allocation.py#L261-L262 For an 8-hour request on a 7.6h/day schedule, this results in ~1.052631579 days. In `_get_title`, this value is multiplied back to show hours: https://github.com/odoo/odoo/blob/ca01e606928a7704c6b2e4f430710f895be2653d/addons/hr_holidays/models/hr_leave_allocation.py#L151 This multiplication leads to the long decimal values being displayed in the title. Solution: --------- Round the computed duration to two decimal places using `float_round`. **NOTE:** This issue is already fixed in saas-19.1 (commit 01d86a7). However, **no change** is required in the multi-allocation wizard, as the duration there directly uses user input and is not computed from working hours. opw-6091424 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260140
This update fixes a bug where untaxed invoice lines were incorrectly inheriting datev codes from previous lines in the general ledger export. This ensured accurate datev reporting for German companies, preventing potential discrepancies in financial reports. The fix corrects the CSV file generated for Datev, ensuring proper accounting line identification.
Original PR description
**PROBLEM** Untaxed move lines would take the datev code of the previous line instead of having no datev code like they should. **STEP TO REPRODUCE** 1. On a german company, create an invoice with a line with tax 19% I, and a line that is untaxed (with a non-null price). 2. On the general ledger, generate the datev zip. 3. Unzip, and open the account entries csv, and notice the 2nd line of the invoice as the datev code set to something instead of it being empty (column BU-Schlüssel). opw-6141003 Forward-Port-Of: odoo/enterprise#118486
This update resolves an error that occurred when confirming DHL deliveries. The system now automatically sets a future delivery date (one hour ahead) to avoid the 'date must be in the future' error, ensuring successful order confirmations.
Original PR description
When confirming the delivery of an order using DHL shipping method we get an error that the date must be in the future. This happens when the scheduled date was not set, or set for a time in the past. This commit automatically sets the time to 1 hour in the future and bypasses the user error. opw-6148927 Forward-Port-Of: odoo/enterprise#116211
A bug was causing grouped payments to incorrectly link existing invoices to new, unrelated invoices. This update fixes the issue by ensuring payments are properly associated with the intended invoices, preventing data duplication and improving payment reconciliation accuracy. This resolves a problem where payments were spreading across multiple invoices.
Original PR description
Steps to reproduce --- 1. Register a grouped customer payment over several invoices, leaving one of them only partially paid. 2. Register a second grouped payment over two invoices: the partially…
Steps to reproduce --- 1. Register a grouped customer payment over several invoices, leaving one of them only partially paid. 2. Register a second grouped payment over two invoices: the partially paid one and a brand new invoice. 3. Open the first payment, its "Reconciled Invoices" smart button now lists the new invoice from the second payment, which it never paid. Issue --- The smart button is built from the stored `invoice_ids` many2many, which shares its relation table with `account.move.matched_payment_ids`. After reconciling, the register wizard links the payment to its invoices with `lines.move_id.matched_payment_ids += payment` at https://github.com/odoo/odoo/blob/f726393267a28cedd5febd2106de17ae3838f3ff/addons/account/wizard/account_payment_register.py#L1212. When the payment groups several invoices, `lines.move_id` is a multi-record recordset. Reading `matched_payment_ids` on it returns the union of the payments already linked to all those invoices, and `+=` writes that union back to every invoice as a `(6, 0, ...)` replace command. So an invoice already paid by an earlier payment spreads that earlier payment onto every other invoice grouped in the new one, including brand new invoices, which then wrongly appear on the earlier payment. opw-6188013 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267968
This update significantly improves the speed of syncing participants to marketing campaigns. By optimizing the underlying code, the process now takes just a fraction of the previous time – reducing it from over 51 seconds to less than a second. This change enhances the performance of our marketing automation tools, especially when managing large campaigns.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#119589 Forward-Port-Of: odoo/enterprise#117656
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must precede the end time, ensuring correct shift template creation. This improves user experience and reduces confusion.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
7 changes
Resolved issues and error corrections
A recent update caused the Asset Depreciation Schedule report to crash when dealing with many assets grouped together. This fix ensures the report handles empty asset values correctly, preventing errors and allowing customers to generate reports without interruption. The change aligns with existing safeguards to ensure data integrity.
Original PR description
#### Description of the issue/feature this PR addresses: Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is…
#### Description of the issue/feature this PR addresses:
Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is active (large number of assets in one account group). The report becomes unusable for affected customers.
#### Current behavior before PR:
_regroup_lines_by_name_prefix sums each subline column by indexing prefix_subline['columns'][i]['no_format'] directly. Empty columns are built as {} by _build_column_dict (both col_value and col_data are None), so they have no 'no_format' key. With a comparison period enabled, an asset that has no value in the comparison period produces an empty column for that period; once prefix grouping fires (len(lines) >= prefix_groups_threshold, default 4000), the direct lookup hits that empty dict and raises KeyError: 'no_format'.
#### Desired behavior after PR is merged:
The prefix group total treats a missing 'no_format' as 0, matching the sibling caller in account_asset/models/account_assets_report.py that already guards with .get('no_format', 0). The report builds without crashing and the empty comparison column contributes 0 to the prefix group total.
opw-6225639
Forward-Port-Of: odoo/enterprise#119088This update fixes a bug where untaxed invoice lines in German accounting reports incorrectly inherited the Datev code from the previous line. This resulted in inaccurate Datev reports, which are crucial for compliance. The fix ensures untaxed lines have the correct, empty Datev code, improving report accuracy and reliability.
Original PR description
**PROBLEM** Untaxed move lines would take the datev code of the previous line instead of having no datev code like they should. **STEP TO REPRODUCE** 1. On a german company, create an invoice with a line with tax 19% I, and a line that is untaxed (with a non-null price). 2. On the general ledger, generate the datev zip. 3. Unzip, and open the account entries csv, and notice the 2nd line of the invoice as the datev code set to something instead of it being empty (column BU-Schlüssel). opw-6141003 Forward-Port-Of: odoo/enterprise#118486
This update resolves an error that occurred when confirming DHL deliveries. The system now automatically sets a future delivery date (one hour ahead) to avoid the 'date must be in the future' error, which previously prevented successful order confirmations. This ensures DHL delivery confirmations can always be processed correctly.
Original PR description
When confirming the delivery of an order using DHL shipping method we get an error that the date must be in the future. This happens when the scheduled date was not set, or set for a time in the past. This commit automatically sets the time to 1 hour in the future and bypasses the user error. opw-6148927 Forward-Port-Of: odoo/enterprise#116211
This update resolves an error that occurred when creating payment reports for Swiss companies using the ‘l10n_ch_hr_payroll’ module. The issue stemmed from a missing module dependency, causing a value error during report generation. This fix ensures the payment report functionality works correctly for all company types.
Original PR description
*=l10n_ch_hr_payroll,hr_payroll_account_iso20022 When clicking the create payment report button on a payslip for a Swiss company, a traceback occurs if the ``hr_payroll_account_iso20022`` module is…
*=l10n_ch_hr_payroll,hr_payroll_account_iso20022 When clicking the create payment report button on a payslip for a Swiss company, a traceback occurs if the ``hr_payroll_account_iso20022`` module is not installed. Steps to reproduce the error: - Install ``l10n_ch_hr_payroll`` module - Switch to CH Company - Create an Employee and running contract for it - Go to Payroll > Payslip > All payslips > Create a new payslip > Set the employee > Confirm > Create payment report Traceback: ```py ValueError: Wrong value for hr.payroll.payment.report.wizard.export_format: 'iso20022_ch' ``` https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_ch_hr_payroll/models/hr_payslip.py#L383 https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/l10n_ch_hr_payroll/models/hr_payslip_run.py#L13 Here, ``iso20022_ch`` is passed as ``export_format``, However, ``iso20022_ch`` is added to the selection field in the ``hr_payroll_account_iso20022`` module at [1]. When that module is not installed, the selection value does not exist, leading to the above error. [1]: https://github.com/odoo/enterprise/blob/7792926504a823590fbbe574a96994002a92fc17/hr_payroll_account_iso20022/wizard/hr_payroll_payment_report_wizard.py#L11 sentry-7391832811 Forward-Port-Of: odoo/enterprise#113277
This update significantly speeds up the process of adding and removing participants from marketing campaigns, particularly for large campaigns. The change optimizes how the system identifies and manages participants, reducing processing time from over 51 seconds to just 0.65 seconds. This improvement enhances campaign performance and user experience.
Original PR description
Replace search_read with search_fetch to avoid unnecessary _read_format call in backend context. Use OrderedSet instead of a custom _uniquify_list helper to get O(1) membership tests when computing records to add or remove from campaigns. Benchmark on a campaign with 115k participants: | Before PR | After PR | |:---------:|:--------:| | 51.71s | 0.652s | opw-6055334 Forward-Port-Of: odoo/enterprise#119589 Forward-Port-Of: odoo/enterprise#117656
This update fixes a misleading error message displayed when a shift template's start time was set after its end time. The message has been corrected to accurately state that the start time must be before the end time, ensuring correct shift template creation. This improves user experience and prevents confusion.
Original PR description
Before this commit, when the user set a start hour after end hour, the error message raised said: "The start hour cannot be before the end hour for a one-day shift template.". Which does not make sense since the start hour has to be before the end hour to be valid. This commit fixes the error message to say the start hour cannot be after the end hour. Forward-Port-Of: odoo/enterprise#119637
A test failure in the SendCloud delivery module was resolved by adding default accounting data to the test environment. This prevents a database error related to missing tax information, ensuring test runs complete successfully. This fix addresses a runbot error and improves the stability of the delivery process.
Original PR description
Without demo data, test `test_sendcloud_delivery_with_downpayment` fails because of the absence of a default `account_tax` > psycopg2.errors.NotNullViolation: null value in column "tax_group_id" relation "account_tax" violates not-null constraint Fixes runbot errors 243069 - 243677 - 939245 Forward-Port-Of: odoo/enterprise#118639
23 changes
New functionality added to Odoo
This update introduces two new work entry types for Belgium payroll – ‘Public Holiday Working (Without Recovery)’ and ‘Public Holiday Working (To Recover)’. These additions allow for more accurate tracking of employee time worked during public holidays, ensuring compliance with Belgian labor laws and improving payroll reporting.
Original PR description
[IMP] l10n_be_hr_payroll: new public holiday time work entry type I added two new work entry type Public Holiday Working (Without Recovery) and Public Holiday Working (To Recover) task - 6275564
This update adds support for Belgian unemployment benefits within the payroll system. It includes new salary rules and adjusts the departure flow to accurately reflect payments related to economic unemployment, ensuring compliance with local regulations.
Original PR description
-Salary Rules and parameters -Change in departure flow for unemployment Task#5914315
This update introduces an automated system for generating and posting payslips for certain employee types, such as company executives, where payroll data is rarely reviewed by HR. A daily cron action now checks for these types with approaching closing dates and automatically creates and validates payruns, streamlining the payroll process.
Original PR description
For some employee types e.g. company executive, payslips are most of the time always the same and not managed by any HR people (as they can not see the payroll data of company executives), so we need a mechanism to automate the generation of the payslips. This PR adds an option on employee type to automatically post the payslip run when the closing date is reached. It does so through a cron action that runs daily and checks if there are employee types with auto post enabled and a closing date reached, then creates and validates payruns for those employee types. task-6191997
Enhancements to existing features
This update introduces automated warnings for key payroll reports (281, 273S, 274, and Dmfa) to help payroll officers avoid missed deadlines. The system now provides customizable alerts with clear instructions and actions, streamlining the reporting process and reducing the risk of errors. This enhancement improves operational efficiency and ensures timely report submission.
Original PR description
Purpose: A lot of reports must be done and submitted monthly, quarterly, yearly. For a payroll officer it can quickly become a mess and he can quickly miss a deadline. Current behavior: - added new options for `closing_on` on dashboard warnings - added more fields to be customizable in the python code of the warning (warning_title, warning_description, warning_deadline, warning_button) - added warnings for 281, 273S, 274 and Dmfa reports with the corresponding dialogs and needed actions task-id: 5909165
This update introduces a new report for payroll officers, providing a clear view of employee end-of-service benefit amounts. Officers can now control the report's parameters and export the data for detailed analysis, improving payroll accuracy and reporting.
Original PR description
In order to facilitate the usage of odoo for payroll officers and give the required visibility over the end of service benefit amount for all employees, a separate report has been introduced which will allow the officers to control the end date and employees they are inspecting and export it for further investigation. Task: 4860227
This update streamlines the processing of subscription renewals within Odoo Enterprise. By moving renewal logic to a queued, post-processing system, it improves efficiency and aligns with the existing deferred payment confirmation process. This change enhances the reliability and performance of subscription renewals.
Original PR description
*: `appointment_account_payment`, `sale_subscription`, `sale_subscription_external_tax` See the related community commit for the motivation behind these changes. The auto-renewal cron of `sale_subscription` was adapted to no longer assess transaction states or run business-specific logic synchronously, instead relying entirely on post-processing, thus unifying that flow with the deferred payment confirmation path. task-4309611 See also: - https://github.com/odoo/odoo/pull/255611
This update introduces a new button on the salary rule category list view, providing a quick way for users to see all associated salary rules – including those within sub-categories. This streamlines the process of managing salary rules and simplifies reporting.
Original PR description
This commit adds a fast way to access this information by introducing a smart button directly on the salary rule category list view, allowing users to view all the salary rules linked to a category (including those connected to its sub-categories). Task Id : 6283798
This update enhances the employee calendar view within payslips by automatically graying out days with no scheduled attendance or when an employee isn't assigned to work. This provides a clearer visual representation of an employee's working hours, simplifying payroll processing. The change was implemented to improve the accuracy and usability of the payroll system.
Original PR description
In this commit, expected: - Gray out the calendar when no attendance is scheduled or the employee is not supposed to work Step to produce - Create Working Hours schedule, remove Friday under working hours tab - Assign the working hours schedule to employee - Create new payslip for employee - Click Calender SmartButton to see Employee Calender View from Payslip task: 6260186
Resolved issues and error corrections
This update fixes a visual issue with the indeterminate checkbox in the Enterprise version of Odoo. The change ensures the checkbox's indicator is consistently visible across all environments, resolving a prior workaround. This improves the overall user experience and consistency.
Original PR description
The indeterminate checkbox is a [standard API](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:indeterminate#:~:text=true%3B%0A%7D-,Result,-Play) (JS and CSS only as @pparidans…
The indeterminate checkbox is a [standard API](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:indeterminate#:~:text=true%3B%0A%7D-,Result,-Play) (JS and CSS only as @pparidans noted), which has been implemented in Odoo in a couple of different ways, and is currently not working out-of-the-box (enterprise only): ------ PROBLEMS: - Original implementation was with JS because of a (now fixed) owl issue: see [ web/static/src/search/search_panel/search_panel.xml](https://github.com/odoo/odoo/blob/c0c82927f2e7e2a54749a0e081d8a03b9ef654e2/addons/web/static/src/search/search_panel/search_panel.xml#L99-L103) & https://github.com/odoo/owl/issues/713 - The new intended odoo-api for the indeterminate checkbox (`t-att-indeterminate` or `<Checkbox indeterminate="...")` doesn't work with enterprise installed because: `web_enterprise/static/src/scss/bootstrap_overridden.scss` sets `$component-active-color: unset !default;` & Bootstrap's uses `$form-check-input-indeterminate-color: $component-active-color` therefore resolves to `unset`, making the dash invisible. -> This was fixed in studio only (odoo/enterprise#81372) but should apply globally. ------ FIXES: - Refactor the JS workaround to use the `t-att-indeterminate`, simplifying the code in `web` (with the help of owl magic) - Apply the studio fix globally to enterprise module (we keep the studio fix with custom svg because the color pattern of studio is a bit different, so removing the custom svg makes the UI look less good). Community PR: https://github.com/odoo/odoo/pull/268491
This update ensures that the phone numbers dialed through the Odoo Enterprise system now use the sanitized E164 format, rather than the raw, user-entered number. This change improves accuracy and reliability when making calls or sending messages, aligning with updated phone widget functionality.
Original PR description
This commit ensures that the sanitized phone number is the one passed to the softphone + displayed instead of the raw phone number. Task-5184717 Community: https://github.com/odoo/odoo/pull/261001
This update fixes an issue where the manual prorata year selection for Belgian VAT returns wasn't being saved correctly. Previously, the system defaulted to the current year regardless of user input. The fix ensures that the user's chosen prorata year is accurately reflected in the generated VAT XML, improving data accuracy and compliance.
Original PR description
### Issue before this commit: Manually modifying the "Prorata Year" in the Belgian VAT return lock wizard was ignored. The generated XML always exported the tax return's current year instead of the user's input. ### Steps to reproduce the issue: 1. Download Accounting and l10n_be 2. Switch to BE company 3. Open a tax return for 7 April (as an example) 4. Try to validate the VAT March 2026 ### Cause of the issue: The prorata_year field was a computed field lacking the store=True attribute. Upon validation, the unsaved manual input was lost, triggering the compute method which blindly overwrote it with the default year. https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/l10n_be_reports/wizard/vat_return_lock_wizard.py#L18 ### Reason to introduce the fix: Adding store=True ensures the user's manual override is persisted in the database and correctly injected into the Intervat XML payload. opw-6165520
This update consolidates three separate rules related to unpaid leave into a single, more efficient process. This change creates a central source of truth for calculating unpaid days, improving accuracy and reducing complexity in payroll processing. The update also includes a related test to ensure the new rule functions correctly.
Original PR description
Purpose: As of now, we have 3 seperate rules and all of them deal with the same deductable items which is (Unpaid leave). so instead of doing that, we need to have one source of truth for unpaid days. Current behavior: - dropped the out of contract salary rule - removed the fully unpaid sick leaves from sick leave deduction rule - grouped unapid leaves, unpaid sick leaves and out of contract days under one rule - reintroduced deleted test task-id: 6229123
This update strengthens the validation process for recruitment integration settings. Specifically, a required label has been added to the integration_state_selection field, ensuring data integrity and preventing errors. This improves the reliability of the recruitment process by enforcing correct configuration.
Original PR description
This commit adds a label to the option of the field integration_state_selection. The label is a mandatory property and an error is thrown if it is not given.
This update fixes an issue where the activity rate used in Swiss payroll calculations was incorrectly tied to individual employees. Now, the rate is based on the Odoo Enterprise version, ensuring accurate and compliant payroll processing for Swiss businesses. This change improves the reliability of financial reporting and payroll accuracy.
Original PR description
…ployee Forward-Port-Of: odoo/enterprise#119658
Features or functions removed from Odoo
This update removes a redundant and potentially confusing option within the enterprise sale timesheet functionality. Previously, users could input negative values on timesheets, a feature that was later disabled but remained as an option. This change simplifies the system and aligns with current best practices.
Original PR description
- The '03_timesheet_revenues' option was available because it was previously possible to create timesheet with negative values.This feature was later removed, but the option was left. - removed 03_timesheet_revenues from the possible billable types. task-4610889
Code cleanup and technical improvements
This update modernizes how Odoo Enterprise tracks relationships between records using Owl 3's signal system. It replaces older 't-ref' references with the new Owl 3 signals, ensuring compatibility with the latest Odoo version. This change improves the stability and future-proofing of the Enterprise Companion.
Original PR description
## `t-ref` string refs → Owl 3 signals (enterprise companion) Enterprise side of the Owl 2 → Owl 3 ref-semantics migration. Pairs with the community PR of the same branch name (`master-tref-pr-3-nby`). ### Scope **Leaf 1** companion — enterprise consumers of the migrated mail/web components. ### Notes - Rebased onto current enterprise `master` (2026-06-10). - Community PR: odoo/odoo#269266
This update modernizes how Odoo Enterprise tracks related records by migrating to Owl 3's signal-based referencing system. This change improves the underlying architecture and ensures compatibility with future Owl releases. It primarily impacts components used in the Enterprise Companion.
Original PR description
## `t-ref` string refs → Owl 3 signals (enterprise companion) Enterprise side of the Owl 2 → Owl 3 ref-semantics migration. Pairs with the community PR of the same branch name (`master-tref-pr-4-nby`). ### Scope **Leaf 2** companion — enterprise consumers of `AutoComplete` / input hooks. ### Notes - Rebased onto current enterprise `master` (2026-06-10). - Community PR: odoo/odoo#269267
This update modernizes how Odoo Enterprise references documents and other data by transitioning to Owl 3's signal system. This change improves the underlying architecture and ensures compatibility with future Odoo releases. It impacts several key modules within the Enterprise edition.
Original PR description
## `t-ref` string refs → Owl 3 signals (enterprise companion) Enterprise side of the Owl 2 → Owl 3 ref-semantics migration. Pairs with the community PR of the same branch name (`master-tref-pr-5-nby`). ### Scope **Leaf 3** companion — `documents` `useNestedSortable`, datetime, call-card `useHover` consumers. ### Notes - Rebased onto current enterprise `master` (2026-06-10). - Community PR: odoo/odoo#269268
This update modernizes the way Odoo Enterprise tracks signatures by transitioning to Owl 3's signaling system. It improves the underlying architecture for signature requests, aligning with the latest Owl version and ensuring compatibility with future updates. This change primarily impacts the Enterprise Companion module.
Original PR description
## `t-ref` string refs → Owl 3 signals (enterprise companion) Enterprise side of the Owl 2 → Owl 3 ref-semantics migration. Pairs with the community PR of the same branch name (`master-tref-pr-6-nby`). ### Scope **Leaf 6** companion — sign `ControlPanel` / `NameAndSignature` adaptation. ### Notes - Rebased onto current enterprise `master` (2026-06-10). - Community PR: odoo/odoo#269269
This pull request updates the way attachment previews are handled across several Odoo modules, specifically incorporating a new syntax for OWL 3. This change improves the consistency and reliability of attachment previews within the Enterprise edition, ensuring better functionality for users.
Original PR description
Enterprise counter-part. task-6255532 https://github.com/odoo/enterprise/pull/118962
This update simplifies how controllers access website-related data. Previously, a function called `get_current_website` was used, which has been replaced with a more direct method leveraging the Odoo environment. This change ensures consistent website functionality across various modules and improves maintainability.
Original PR description
All locations that used `get_current_website` can be replaced in the controllers because `website_id` is automatically present in the `context` for routes with the attribute `website=True`.
This update simplifies invoice processing by merging the `l10n_co_dian` module into the core `l10n_co_edi` module. Additionally, the `l10n_co_edi_mandate` module is also integrated, streamlining the system and reducing complexity. This change improves maintainability and aligns with the primary invoice delivery method.
Original PR description
Since the main, and only, way to send invoice is using dian it only makes sense to merge the `l10n_co_dian` module into the main `l10n_co_edi` module. Since the `l10n_co_edi_mandate` module was only introduced as a separate module because of stable policy we also merge it into `l10n_co_edi`. task-5113421
This update refactors the connection between overtime records and employee attendance, improving data accuracy and efficiency. Previously, a workaround was used, but this commit establishes a proper Many2One relationship, aligning with best practices and simplifying future maintenance. This change enhances the reliability of attendance tracking.
Original PR description
In odoo/odoo#241457 we made the relationship between overtime and attendance a m2o
using time_start and employee_id as keys to attribute an overtime to its attendance.
This wasn't ideal but was what was possible with the stable policy. In this commit we
complete that fix by changing the relationship to a proper Many2One.
task-617245210 changes
Resolved issues and error corrections
This update fixes an issue where the VAT reports for Spanish companies were incorrectly including withholding taxes in the total VAT calculation. The fix excludes 'retencion' (withholding tax) from the VAT calculation, ensuring accurate VAT reporting figures. This improves the reliability of financial reports.
Original PR description
Step to reproduce - install `l10n_es_reports` and switch to ES company - create a invoice, add a product, set price = 100 - add two taxes (one should be withholding tax) ex: 21%G and 19%whi - confirm it, total payable is now 100 + 21 - 19 = 102 - open vat Books report for ES, see line for this invoice Observation: - for this invoice, in total vat column, we get 102 value - it should be 100+ 21 i.e 121 as we do not include withholding taxes in total vat Cause: - the query for report used to sum up all the taxes for calculating vat Fix: - excluded tax of type "retencion" in tax summation opw-6082329
This update resolves an issue where generating the general ledger report could create extremely large PDF files due to lengthy invoice references. By limiting the length of invoice references, we prevent the PDF from becoming bloated and ensure reports generate reliably, avoiding system errors related to file descriptor limits.
Original PR description
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single…
The display name of the account.report.line in the general ledger report has the format of: INVOICE NAME (invoice refs) In the case where a client has hundreds of sales orders batched to a single invoice, the ref can become extremely long, e.g.: INV/2026/00001 (S12123, S12152, S12159, S12140, S12165, S12161, S12162, S12110, S12099, S12124, S12145, S12128, S12114, S12131, S12097, S12185, S12154, S12133, S12190, S12118, S12116, S12102, S12155, S12153, S12158, S12150, S12100, S12142, S12121, S12122, S12111, S12187, S12172, S12177, S12095, S12117, S12144, S12137, S12092, S12138, S12186, S12182, S12112, S12148, S12183, S12101, S12178, S12119, S12169, S12115, S12146, S12093, S12126, S12160, S12163, S12129, S12098, S12151, S12096, S12174, S12120, S12130, S12147, S12180, S12191, S12164, S12141, S12105, S12136, S12139, S12109, S12106, S12104, S12103, S12175, S12179, S12188, S12113, S12173, S12167, S12171, S12134, S12094, S12184, S12166, S12170, S12125, S12135, S12143, S12176, S12189, S12156, S12181, S12107, S12157, S12132, S12149, S12127, S12108, S12168...) Because the length of the account.report.line is unchecked in account_general_ledger.py label builder, the pdf can clog to one or two account.report.lines per page, skyrocketing the pdf page length. As wkhtmltopdf processes the report from html to pdf it makes a system call openat() to the /tmp/report.footer.tmp.x.html file for EACH page of the pdf. You can see the TODO comment in the spoolTo function in wkhtmltopdf (both in Odoo and the original repo) saying that the header and footer need to be freed, on each page processing, not just null pointed. https://github.com/odoo/wkhtmltopdf/blob/2c884bd1545b8a639847de22f24754ee5a6fc44c/src/lib/pdfconverter.cc#L794 I verified that that the number of openat calls to the /tmp/report.footer.tmp.x.html file equals the exact number of pages in the pdf to be generated if the report HAD generated successfully by setting the footer input into _run_wkhtmltopdf to None, generating the report without footers, then separately running an strace on wkhtmltopdf when the report fails to generate. See related ticket linked at bottom. The linux machine used on sh instances has a ulimit -n of 1024 file descriptors. Because the footer file descriptors accumulate, once a pdf has about 1010+ pages (~a dozen fd's are allocated for other purposes), over 1024 file descriptors are opened and the system fails with: Wkhtmltopdf failed (error code: -6). Message: QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe Since wkhtmltopdf is archived and Odoo has a replacement in development, I suggest that we limit the display_name of the account.report.line to 200 to keep the bloat minimized, preventing one account.report.line's name from taking up an entire page of the general ledger pdf. This allows many more batched invoices to be shown in the report and a much greater time range of data to be printed without hitting the fd limit. I suggest changing it at the general ledger report level rather than in the account.move.line _compute_display_name function, as we probably still want to see the full display_names at the invoice level. On runbot, the machine has different memory constraints than on sh / local, so it hits the following error before the one above: Wkhtmltopdf failed (error code: -11). Memory limit too low or maximum file number of subprocess reached. Message : Steps to Reproduce on 19.0 newdb: 1. newdb -n test_gl -v 19.0 2. ensure ulimit is set to 1024 in shell that runs odoo instance by running ulimit -n 1024 to mimic ulimit of sh environment 3. run db with python3 odoo-bin, ensuring high enough memory constraints to simulate multi worker sh instance, i.e. --limit-memory-soft=12884901888 --limit-memory-hard=1288490188 4. install sales, accounting, stock 5. install demo data 6. create invoices with 100+ associated sales orders 7. generate the pdf 8. Increase the amount of invoices till the general ledger page count hits ~1010+, where you will hit the error. Notes: opw-ticket-6201508 closes #118067
This update corrects a reporting issue where tax reports for Moroccan companies were incorrectly including entries with zero balances. The fix filters out these zero-balance lines, ensuring the reports accurately reflect financial data. This improves the reliability of tax reporting for our Moroccan clients.
Original PR description
When generating the tax report for a Moroccan company, entries with a zero balance were appearing in the report. Steps to reproduce: ------------------- * Create a Moroccan company * Create a bill with a tax to pay * Change the bill date and accounting date to a past date * Make a first payment of the bill, with a date to today * Unreconcile the payment, and make a second payment with a date in the past (the same one as the bill date for example) * Now generate the tax report for the period of today > Observation: The report contains useless entries with a zero balance. Why the fix: ------------ We add `HAVING SUM(account_move_line.balance) != 0` to filter out the line that have a zero balance. opw-5911669
This update addresses a performance issue within the Dimona payroll module for Belgium. By adding missing indexes to key database tables, the system now processes payroll calculations more efficiently, reducing potential delays and improving overall responsiveness. This enhancement ensures smoother and faster payroll processing for our Belgian clients.
Original PR description
opw-6241383 runbot-233176
This update resolves an issue where inventory counts weren't accurately recording products without lot numbers. The fix ensures that new units without lots are correctly added to inventory counts, preventing miscounts and improving data accuracy. It addresses a validation error related to how the system handles lotless products during inventory adjustments.
Original PR description
### Steps to reproduce: 1. Create a product tracked by lot 2. Put 10 units in WH/Stock without lot 3. Inventory > Operations > Adjustments > Physical Inventory 4. Select the line referring to your…
### Steps to reproduce: 1. Create a product tracked by lot 2. Put 10 units in WH/Stock without lot 3. Inventory > Operations > Adjustments > Physical Inventory 4. Select the line referring to your product and request an inventory count + Show Expected Quantity 5. Open the barcode app > Count Inventory 6. Scan your product #### > The line is not selected, in particular, next scans will be re-interpreted as product scans rather than new serial creation for your product. ### Cause of the issue: Scanning your product search a line to select if any: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1432-L1435 https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1630-L1632 However, the `findLine` will fail since this method calls the `_canOverrideTrackingNumber` to determine if the lot of the barcodData matches the one of the line: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L1859-L1863 But, the override of the `_canOverrideTrackingNumber` method for the `BarcodeQuantModel` does not handle the absence of lotName in the barcodeData correctly as it does not consider that a line without lot can be overridden by an empty lotName: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_quant_model.js#L729-L731 Note however that the super call does: https://github.com/odoo/enterprise/blob/bce04ce24b66fb1a2481274eb3aebdc30a62766e/stock_barcode/static/src/models/barcode_model.js#L795-L798 ### Issue 2: ### Steps to reproduce: - Steps 1 -> 5 - Click on your product line to select it - Scan a new lot to add one new unit referring to that lot - Confirm (1) - Apply Now #### > User Error: Quant's editing is restricted, you can't do this operation Since the line is selected, you have a currentLine during the `processBarcode` and hence the existing line will be updated using the `lotName``: https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/stock_barcode/static/src/models/barcode_model.js#L1560-L1584 However, writing on the line will then try to write on the related quant during the validation process which will be forbiden since we are not allowed to change the lot of an existing quant: https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/addons/stock/models/stock_quant.py#L351-L360 Now, the issue is that actually due to the nature of the line and of the barcode data, the line lot is not expected to be updated but rather a new line is expected to be created: https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/stock_barcode/static/src/models/barcode_model.js#L795-L798 Additional issue: Fixing issue 1 and 2 highlight and other issue of the validation process: - Steps 1 -> 6 > The line gets selected - Scan a newlot > a new subline is added referring to 1 unit of your new quant - Confirm (1) > Some serials where not counted, set them as missing #### > Check your quants: the 10 unit lotless quant was not updated but a new quant for 1 units was created for your newlot ### Cause of the issue: Applying all quantities is expecting to toggle them as counted before applying to update the existing quants: https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L72-L82 https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L287-L296 However, only line tracked by serial numbers are set as counted: https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/stock_barcode/static/src/models/barcode_quant_model.js#L60-L63 opw-6212923
This update corrects a bug in the accrual reports (like 'Bill To Receive') that caused group totals for 'Received,' 'Billed,' and 'Amount' to incorrectly show as zero. The fix ensures these reports accurately reflect aggregated data, which is essential for accountants during financial closing processes. This improves the reliability of key financial reporting.
Original PR description
### Issue before this commit: In accrual reports (e.g., "Bill To Receive", "Billed Not Received", "Invoices To Be Issued", and "Invoices Not Delivered"), when grouping the list view by fields such as…
### Issue before this commit: In accrual reports (e.g., "Bill To Receive", "Billed Not Received", "Invoices To Be Issued", and "Invoices Not Delivered"), when grouping the list view by fields such as Vendor, the group header totals for the "Received", "Billed", and "Amount" columns display 0.00 even if the interanl lines of the group are not 0.00. ### Steps to reproduce the issue: 1. Download Purchase Accounting and Sale Accounting 2. Go to one of this pages: Billed Not Received, Bill To Receive, Invoices To Be Issued, and Invoices Not Delivered 3. Ensure the view is in its default grouping (grouped by Vendor or Customer) 4. Observe the group header rows for the Received (or Delivered), Billed (or Invoiced), and Amount columns. They all display 0.00 5. Expand a group that contains records with values greater than zero 6. Observe that the individual records populate correctly, but the aggregated group header row continues to display 0.00. ### Cause of the issue: The commit ddc1b681656ea8c70f3231cda20b5a58b9ff7dd6 adapted the code to retrieve the new accrual reports but attempted to fetch grouped records using group[0].id as the dictionary key, while the grouped() method actually used the recordset object as the key. This mismatch caused the dictionary lookup to fail, resulting in 0.00 sums. https://github.com/odoo/enterprise/blob/c8535a7a0e2eae811048a34a0bae187a1fa45311/account_accountant/models/analytic_mixin.py#L40-L48 ### Reason to introduce the fix: This fix restores the core analytical utility of the accrual reports, which are crucial for accountants during period-end closings to evaluate totals at a glance. opw-6232273
This update fixes an issue where adding a recurring product to a confirmed sales order without a linked subscription plan would cause an error. The change prevents this by validating the product type and displaying a user-friendly error message, ensuring correct recurring product setup.
Original PR description
Steps to reproduce: - Go to Sales → Products. - Create a Service product and enable the Recurring option. - Open an already confirmed Sales Order that does not contain any recurring products. - Add the newly created recurring product to the confirmed order. - Click Save. - Observe that a traceback occurs. Cause: - When adding a recurring product without a subscription plan to a confirmed Sale Order, _timesheet_create_task() attempts to compute a start date using order.next_invoice_date, which is not set. - This leads to a TypeError when `order.next_invoice_date` receives `False`. Solution: - Add a validation to prevent adding recurring products without a subscription plan and raise a proper `UserError` instead of allowing the code to reach task generation logic. task-5932700 Forward-Port-Of: odoo/enterprise#119942 Forward-Port-Of: odoo/enterprise#107691
This update fixes a bug where untaxed invoice lines in German reports incorrectly inherited the Datev code from the previous line. The fix ensures that untaxed lines now properly display an empty Datev code, aligning with German tax regulations. This prevents reporting discrepancies and ensures accurate financial data for Datev.
Original PR description
**PROBLEM** Untaxed move lines would take the datev code of the previous line instead of having no datev code like they should. **STEP TO REPRODUCE** 1. On a german company, create an invoice with a line with tax 19% I, and a line that is untaxed (with a non-null price). 2. On the general ledger, generate the datev zip. 3. Unzip, and open the account entries csv, and notice the 2nd line of the invoice as the datev code set to something instead of it being empty (column BU-Schlüssel). opw-6141003 Forward-Port-Of: odoo/enterprise#118486
This update ensures that undoing the auto-plan feature correctly preserves the initial workload assigned to a shift. Previously, the system recomputed the workload, leading to inaccurate shift allocations. This fix maintains the intended functionality of the auto-plan process.
Original PR description
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation…
Steps to Reproduce --- 1. Open the Planning module 2. Create an open shift with allocated_hours 3. Click Auto Plan 4. Click Undo on the auto-plan notification Issue --- Undoing an auto-plan operation triggers recomputation of allocated_hours, causing the shift to lose its original workload value. Current Behaviour --- When resource_id is set to False during undo: - _compute_allocated_hours is triggered (depends on resource_id) - _compute_allocated_percentage is triggered (depends on allocated_hours) - Both fields are recalculated, potentially changing allocated_hours from its pre-assignment value Expected Behaviour --- Undoing auto-plan should preserve allocated_hours at its pre-assignment value while allowing allocated_percentage to adapt to the new context (open slot vs assigned resource). Fix --- Use protecting context manager in action_rollback_auto_plan_ids to prevent allocated_hours from being recomputed when resource_id is removed. This allows allocated_percentage to recalculate naturally based on slot duration while keeping allocated_hours stable. task - 4952149 Forward-Port-Of: odoo/enterprise#119772 Forward-Port-Of: odoo/enterprise#102864
This update resolves an error that occurred when confirming DHL deliveries. The system now automatically sets a future delivery date (one hour ahead) to avoid the 'date must be in the future' error, which previously prevented successful order confirmations. This ensures DHL delivery confirmations can always be processed.
Original PR description
When confirming the delivery of an order using DHL shipping method we get an error that the date must be in the future. This happens when the scheduled date was not set, or set for a time in the past. This commit automatically sets the time to 1 hour in the future and bypasses the user error. opw-6148927 Forward-Port-Of: odoo/enterprise#116211
7 changes
Resolved issues and error corrections
This update fixes a security issue where users could view financial budgets belonging to other companies. The change adds a security rule to the budget module, ensuring that users only see budgets associated with the company they are actively working with. This enhances data privacy and control.
Original PR description
**Steps to reproduce:** - Install the `account_reports` module. - Create a new company. - Navigate to Accounting > Configuration > Financial Budgets. - Create a new budget record. - Switch to another company. - Open the list view of Financial Budgets. **Observation:** The budget record created in another company is still visible. **Root Cause:** The model `account.report.budget` does not have any record rule restricting access based on company. As a result, users can see financial budgets belonging to other companies even if they are not connected to them. **Fix:** This commit allows users to hide financial budgets from companies they are not connected to by adding a record rule on `account.report.budget` opw-6083892
This update fixes an issue where HR users couldn't update employee information, specifically related to payroll slip IDs. The change allows HR staff to modify employee records without errors, ensuring consistent data management. This resolves a restriction that prevented updates, streamlining HR processes.
Original PR description
Steps to reproduce: -------------------------- 1. Install l10n_ch_hr_payroll_elm_transmission. 2. Switch to a Swiss company. 3. Create an employee and create a user with HR rights but without Payroll…
Steps to reproduce: -------------------------- 1. Install l10n_ch_hr_payroll_elm_transmission. 2. Switch to a Swiss company. 3. Create an employee and create a user with HR rights but without Payroll rights. 4. Log in with this new user. 5. Update any value on the employee form (e.g., marital status or add a tag). Issue: ----------- Updating the employee raises the following error: ```python You do not have enough rights to access the fields "slip_ids" on Employee (hr.employee). Please contact your system administrator. Operation: read User: 2 Fields: - slip_ids (allowed for groups 'Payroll / Officer: Manage all contracts') ``` Cause: --------- After this 4416eda, open payslips are recomputed automatically on every employee update: https://github.com/odoo/enterprise/blob/8f7a43eebdc8f7f46f9d61ab7084e036c20f778e/l10n_ch_hr_payroll_elm_transmission/models/hr_employee.py#L210-L213 `slip_ids` is restricted to payroll users: https://github.com/odoo/enterprise/blob/8f7a43eebdc8f7f46f9d61ab7084e036c20f778e/hr_payroll/models/hr_employee.py#L14 As a result, when an HR user without payroll rights updates an employee, accessing slip_ids raises an **AccessError**. Solution: ----------- Use sudo() when accessing slip_ids so HR users can update employee records without issue. **NOTE:** The issue has been resolved from version saas~18.4 with the following commits: 279f09a9587674c035c514f966788a4dddfe9794 and 75d66d8 opw-6210358
This update resolves an issue where SEPA QR codes were occasionally displaying incorrect decimal places due to floating-point calculations in the system. The change ensures the QR code amount accurately reflects the currency's precision, preventing potential payment errors. This improves the reliability of vendor bill payments generated via QR code.
Original PR description
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of…
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of respecting the currency's expected precision. This occurs because the `amount` variable in `_get_qr_vals` was being converted directly using `str(amount)`. Due to Python's floating-point arithmetic, the float value in memory can contain decimal drift. Directly casting it to a string exposes this drift in the payload. This commit resolves the issue by replacing `str(amount)` with `float_repr(amount, currency.decimal_places)`. This safely bypasses the float representation issue, ensuring the string strictly respects the currency's configured decimal precision before being injected into the QR code. opw-5504258 **Steps to reproduce:** - Select company “My Belgian Company” - Create a 23% purchase tax - Create vendor bill - Select Vendor “BE Company CoA” - Choose any single product, change price to 37.18 and choose the 23% tax. The Untaxed Amount should be 37.18, VAT tax should be 8.55, and Total should be 45.73 - Confirm > Register Payment > scan QR code. EUR45.730000000000004 should show **Current behavior before PR:** - When generating a SEPA QR code for a payment, the embedded amount can contain excess decimal places due to floating-point drift. **Desired behavior after PR is merged:** - The SEPA QR code is generated with the correct number of decimal places. Forward-Port-Of: odoo/odoo#267293
This update fixes a bug where untaxed invoice lines were incorrectly inheriting the Datev code from the previous line, leading to inaccurate reports. The change ensures that untaxed lines now correctly have an empty Datev code, resolving a reporting discrepancy. This improves the accuracy of financial reports generated for German businesses using the Datev system.
Original PR description
**PROBLEM** Untaxed move lines would take the datev code of the previous line instead of having no datev code like they should. **STEP TO REPRODUCE** 1. On a german company, create an invoice with a line with tax 19% I, and a line that is untaxed (with a non-null price). 2. On the general ledger, generate the datev zip. 3. Unzip, and open the account entries csv, and notice the 2nd line of the invoice as the datev code set to something instead of it being empty (column BU-Schlüssel). opw-6141003 Forward-Port-Of: odoo/enterprise#118486
This update resolves a problem where DHL delivery confirmations were failing due to incorrect scheduled dates (past dates). The system now automatically sets a future date (one hour ahead) to ensure successful confirmation, preventing delivery errors and improving order processing.
Original PR description
When confirming the delivery of an order using DHL shipping method we get an error that the date must be in the future. This happens when the scheduled date was not set, or set for a time in the past. This commit automatically sets the time to 1 hour in the future and bypasses the user error. opw-6148927 Forward-Port-Of: odoo/enterprise#116211
This update resolves a rounding issue that occurred when generating PEPPOL invoices, specifically impacting unit prices. The change reverts a previous update that introduced this problem, ensuring accurate pricing calculations for international transactions. This improves the reliability of invoices for our business partners using PEPPOL.
Original PR description
Reverts https://github.com/odoo/odoo/pull/262242 opw-6293201
This update resolves a problem where the PDF Quote Builder generated incorrect data due to how it handled temporary records during the demo setup. The fix ensures that all data changes are immediately applied within the transaction, preventing inconsistencies and errors when the builder is enabled. This ensures the PDF quote builder functions correctly after demo data is used.
Original PR description
Steps to produce: --- - Install sale_management and website_sale modules with demo data. - From settings, disable the PDF Quote Builder. - Go to Settings > Technical > Sequences & Identifiers >…
Steps to produce:
---
- Install sale_management and website_sale modules with demo data.
- From settings, disable the PDF Quote Builder.
- Go to Settings > Technical > Sequences & Identifiers > External Identifiers.
- Delete the `consu_delivery_02_product_template` identifier.
- From settings, try to enable the PDF Quote Builder again.
Issue:
---
```py
insert or update on table "quotation_document_sale_pdf_form_field_rel" violates foreign key constraint
"quotation_document_sale_pdf_form_fie_quotation_document_id_fkey"
DETAIL: Key (quotation_document_id)=(1) is not present in table "quotation_document".
```
Cause:
---
When the XML demo loader processes **`sale_pdf_quote_builder_demo.xml`**, it calls `create()` on `quotation.document` for each of the 5 demo records one by one. Each create() call receives vals_list that contains datas, the actual PDF base64 content.
Inside `super().create(vals_list) `[1], the ORM writes datas to `ir_attachment`. Since `form_field_ids` is a `store=True` computed field with `@api.depends('datas')` [2], the ORM knows it needs to recompute `form_field_ids`. But it does not run the computation immediately. It simply registers the records in a pending recompute set and moves on. Nothing hits the DB yet for this compute.
After `super().create() `returns, the `write({'res_model': ..., 'res_id': ...})` runs. Since `res_model` and `res_id` live on `ir_attachment` (the parent table via _inherits), this write is also not immediately flushed to the DB. The ORM marks it as dirty in the cache and defers it.
So after all 5 records are created, the ORM holds two deferred things: a dirty UPDATE ir_attachment write for all 5 records, and a pending recompute for `form_field_ids` on all 5 records. Nothing has been flushed to the DB yet.
When the demo XML tries to reference `product.consu_delivery_02_product_template` [3], which no longer exists,
a ValueError is raised. From `load_demo()` [4], the savepoint is rolled back.
After the except block logs the failure, execution continues in l`oad_module_graph()` which calls `env.cr.commit()`. This triggers f`lush() -> transaction.flush() -> flush_all() -> _recompute_all()`. The ORM processes the pending recompute registry and finds `form_field_ids` needs recomputing for quotation.document(1, 2, 3, 4, 5). It calls `_compute_form_field_ids`() on those stale ids. Inside that compute, `_create_or_update_form_fields_on_pdf_records()` tries to insert into `quotation_document_sale_pdf_form_field_rel` with quotation_document_id=1. But quotation_document id 1 no longer exists in the DB — it was rolled back — so PostgreSQL raises the foreign key violation.
This is confirmed by the traceback from `_compute_form_field_ids`, which shows the call chain going through `commit() -> flush_all() -> _recompute_all()` rather than through `create()`, proving the compute fired after the rollback using stale ORM cache state.
Fix:
---
Calling `docs.flush_recordset()` at the end of `create()` forces all pending writes and pending recomputes to be executed immediately, while still inside the savepoint scope:
- It flushes the dirty res_model/res_id write on the ir_attachment parent table, so UPDATE ir_attachment hits the DB inside the savepoint.
- It triggers `_recompute_all()` for the pending `form_field_ids` compute on docs, so `_compute_form_field_ids()` runs inside the savepoint and the INSERT into `quotation_document_sale_pdf_form_field_rel` happens while the quotation_document rows still exist in the DB.
If the savepoint then rolls back, the ORM cache has nothing dirty or pending left. The subsequent commit() in `load_module_graph()` finds nothing to flush, so no stale writes execute against non-existent ids and no foreign key violation occurs.
[1]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/sale_pdf_quote_builder/models/quotation_document.py#L93-L98
[2]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/sale_pdf_quote_builder/models/quotation_document.py#L62-L71
[3]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/sale_pdf_quote_builder/data/sale_pdf_quote_builder_demo.xml#L44-L51
[4]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/odoo/modules/loading.py#L89-L90
opw-6139555
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr