Daily updates from Odoo
Wednesday, June 10, 2026
57 changes · saas-19.2
New functionality added to Odoo
This update adds support for the Hacienda Foral de Navarra tax agency within Odoo's SII invoicing system. It adjusts the system to handle the specific XML format and endpoint requirements of this agency, ensuring accurate invoice submissions. This expansion broadens Odoo's compliance capabilities for businesses operating in the Navarra region.
Original PR description
The Hacienda Foral de Navarra uses the same SII XML format as AEAT but sends invoices to a different endpoint. Additionally, Navarra requires explicit XML namespace declarations in the SOAP envelope header, which the standard zeep serializer does not include by default. This adds the Navarra tax agency as a new option in the company SII configuration, defines its production and test endpoints, and injects the required namespaces in the request header when the Navarra agency is selected. task-5946583 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268438 Forward-Port-Of: odoo/odoo#263048
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 'Show Sub-Tasks' option was incorrectly displayed in the mobile My Tasks menu. The fix ensures that this button is hidden in project_todo views, aligning with the functionality of To-do items which do not support subtasks. This improves the user experience on mobile devices.
Original PR description
Steps to reproduce: - Install project - Open the My Tasks menu on mobile view Issue: The "Show Sub-Tasks" option was visible in the My Tasks menu on mobile view. Cause: The condition only applied `showTaskOptions` to the desktop part of the expression, so the dropdown was still rendered on mobile when there were no embedded actions. Apply `showTaskOptions` to the whole condition to properly hide the dropdown in the My Tasks mobile view. Fix-2: Steps to reproduce: - Install project_todo Issue: The Show Sub-Tasks button was visible in project_todo views even though To-do items do not support subtasks. Fix: Ensure that the Show Sub-Tasks button is hidden in project_todo views. task-6026239 Forward-Port-Of: odoo/odoo#255283
This update fixes a visual issue in the portal chatter interface where elements like the Follow/Unfollow button appeared misaligned due to excessive padding. The fix removed a duplicated padding setting that was previously hardcoded in the system, ensuring a cleaner and more professional look for users. This improves the overall user experience within the portal.
Original PR description
**Steps to reproduce:** 1. Log in as a portal user. 2. Open a shared project and then open any task within it. 3. Observe the vertical spacing above the Follow/Unfollow button and the chatter…
**Steps to reproduce:** 1. Log in as a portal user. 2. Open a shared project and then open any task within it. 3. Observe the vertical spacing above the Follow/Unfollow button and the chatter component. **Issue:** The chatter UI has incorrect vertical spacing, causing elements like the Follow/Unfollow button to sit too far down and appear misaligned. **Cause:** The pt-2 padding class was hardcoded in two separate locations: 1. The compileChatter wrapper in project_sharing_form_compiler.js. 2. The portal.Chatter XML template. When combined this caused a double-padding effect forcing excessive space. **Fix:** Removed the hardcoded pt-2 class from both the JavaScript compiler wrapper and the core XML template. This eliminates the double-padding conflict. This resolves the alignment issue in Project Sharing and does not affect the layout or functionality of other portal components. task-4203362 Forward-Port-Of: odoo/odoo#268977 Forward-Port-Of: odoo/odoo#257490
This update resolves an issue where cancelled journal entries were incorrectly showing in the reconciliation view, preventing successful reconciliation and causing data inconsistencies. The fix removes a previous refactor that allowed draft entries, ensuring cancelled entries are properly excluded from reconciliation processes.
Original PR description
Issue: Cancelled journal entries were visible in the "Journal Items to Reconcile" view (action_move_line_posted_unreconciled) because the action domain had no filter to exclude them. This caused…
Issue: Cancelled journal entries were visible in the "Journal Items to Reconcile" view (action_move_line_posted_unreconciled) because the action domain had no filter to exclude them. This caused reconciliation failures, no reconciliation happened, and the cancelled record remained in the view. This regression was introduced during a refactor to allow draft entries in the reconciliation view, where the posted-state condition was removed from the domain: Enterprise commit: https://github.com/odoo/enterprise/commit/003cffabda7d91a6d10d58942ed972ca5e17366d As a result, cancelled journal items also became visible, causing reconciliation attempts to fail while the records remained in the view. Also, we are not allowed to reconcile cancelled move lines, and we already have the validation for this [here](https://github.com/odoo/odoo/blame/a236f67776616f6facdefb0117a6ffdde9b7c84c/addons/account/models/account_move_line.py#L2627) Issue is reproducible on runbot. Here is the video reference: https://drive.google.com/file/d/1ojIDxHn5Yst8gVFy8JyhwtJoDSSSJsmK/view?usp=sharing - OPW: 6247870 Forward-Port-Of: odoo/enterprise#119017 Forward-Port-Of: odoo/enterprise#118773
This update corrects a potential error in the Hong Kong payroll calculations. Specifically, it now checks for situations where a company's resource calendar is missing or if an employee has zero hours per week, preventing a division-by-zero error. This ensures accurate payroll processing for Hong Kong businesses.
Original PR description
. Add a check for a null resource calendar and zero hours per week. task-6229271 Forward-Port-Of: odoo/enterprise#117685
This update resolves an issue where the database upgrade process failed due to dependency on a live NAV service during the Hungarian chart template reload. The fix bypasses the credential validation step, allowing the upgrade to proceed without relying on external connectivity, ensuring smoother updates.
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 glitch in the website builder's carousel feature. Previously, changing image sizes or adding borders could cause layout issues and a jarring effect. The update now automatically adjusts carousel item heights to maintain a consistent display, ensuring a smoother and more reliable user experience.
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 fixes an issue where subtype information was lost when messages were moved between records in Odoo. Now, users will see the subtype description clearly in the chatter interface, providing better context and understanding of the message's purpose. This enhances communication and reduces potential confusion.
Original PR description
Currently, when we move a message from one record to another, the subtype is cleared.Because of this, the description is not visible and the transferred record shows it as empty. In this commit, we append the subtype description into the message body.So the user can see the subtype description in chatter. task-6227750 Forward-Port-Of: odoo/odoo#265003
This update resolves an error that occurred when sending invoices with Danish VAT numbers via Peppol. Now, customers in Denmark can use VAT numbers without the 'DK' prefix, and the system will automatically generate the correct Peppol endpoint. This ensures invoices are properly processed and avoids errors during Peppol transmission.
Original PR description
Current behavior before PR: - Currently, when we include `DK` country prefix in the VAT number, it automatically computes the peppol endpoint with the `DK` prefix for customer from Denmark. - However, there are cases where the VAT number may not include `DK` country prefix, while the corresponding peppol endpoint still does. - In such situations, when sending an invoice via Peppol, the following error occurs: "Errors occurred while creating the EDI document (format: UBL BIS Billing 3.0.12): The VAT of the customer should be prefixed with its country code." Desired behavior after PR is merged: - Now customer from Denmark can have vat without country prefix `DK` and peppol endpoint with prefix `DK` and can send invoice via peppol. task-6119563 Forward-Port-Of: odoo/odoo#263262
This update clarifies error messages when sending invoices via Peppol. Previously, users received a generic "no VAT" message, which was confusing. Now, the system accurately identifies the missing Peppol VAT information (like a Belgian Company Registry), guiding users to complete the required details for successful transmission.
Original PR description
When a user sends a move via Peppol to a customer that has a VAT number set but not a Peppol endpoint, we show the user a generic error ("no VAT").
This makes the user confused, as he already filled the VAT field of his customer, It's the Peppol VAT that is missing (it could be: Belgian Company Registry, France SIRET, ...etc, depending on the customer's country)
This PR makes the error message more accurate by showing exactly the missing required field.
task-5499707
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#266993
Forward-Port-Of: odoo/odoo#245915This update resolves a technical issue where refund orders were generating duplicate invoice numbers for the Spanish tax authority (TicketBAI). The fix ensures unique invoice numbers are used for refund orders, preventing rejection by the tax authority and streamlining the refund process. This improves compliance and avoids delays.
Original PR description
Refund orders use a display name based on the original ticket. The rectificativa was then submitted with a duplicate Serie/NumFactura and rejected with TicketBAI error 5040. Steps to reproduce:…
Refund orders use a display name based on the original ticket. The rectificativa was then submitted with a duplicate Serie/NumFactura and rejected with TicketBAI error 5040. Steps to reproduce: ------------------- * Enable TicketBAI for a Spanish company with POS * Create an order and complete payment (TicketBAI sent) * Refund that order from the POS and complete payment * Open the new TicketBAI XML (downloadable on the order in the backend) > Observation: `CabeceraFactura` `NumFactura` matches the original sale; tax authority returns 5040 (duplicate invoice for same issuer/series/year). Why the fix: ------------ The TicketBAI document `name` was set from `pos.order.name`, so `_get_tbai_seq_from_name` extracted the same numeric part as the original sale. `l10n_es_edi_tbai.document` derives Serie/Num from `name` via `_get_tbai_seq_from_name`. Refund POS names intentionally echo the original order label, so we derive the document name from the same components as non-refund orders (`get_reference_last_part()`), which is unique per receipt. opw-6067965 Forward-Port-Of: odoo/odoo#257475
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 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 resolves an issue where the CODA integration incorrectly prioritized journals. The change creates two journals, selecting the one with the lower ID by default. This ensures the correct currency journal takes precedence, improving the accuracy of CODA reporting and financial data.
Original PR description
The journals[0] is not ideal if the user has one journal with no currency and one with currency that fits the CODA's currency. We'll have two journals and we take the first one at random. Thus if it has a lower id, the journal with no currency will be selected instead of the one whose currency is correct. The latter should take precedence over the former. task-6226835
This update prevents empty ICS calendar files from being generated when users attempt to add open shifts to their calendars. Previously, the system would create an empty file when a matching shift slot wasn't found. Now, the ‘Add to Calendar’ button is hidden and the ICS file is only generated when a valid shift slot is linked to an employee.
Original PR description
**Step:** - install planning - create a resource - create an open shift for a future date - in Gantt view: - publish shift and select the created resource - click “Publish & Send” - check the email and click “Add to Calendar” **Issue:** Currently, clicking “Add to Calendar” generates an empty ics file. **Reason:** During ics file generation, the planning token to find a slot using the planning date and employee. but, no matching slot is found, so the process returns an empty slot, resulting in an empty ics file. **Fix:** Generate the `planning_url_ics` only when a slot is linked with an employee. Otherwise, hide the “Add to Calendar” button and do not generate the ics file. Forward-Port-Of: odoo/enterprise#119838 Forward-Port-Of: odoo/enterprise#118978
This update ensures that new lines added to a sale order from a delivery always include the product's full description, rather than just the display name. Previously, this caused inconsistencies in sales order reporting and tracking. This fix improves data accuracy and reporting reliability.
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 resolves a crash in the payslip PDF report that occurred when employees didn't have a bank account configured. The fix adds a conditional check to the report template, ensuring the bank account section is only displayed if an employee has at least one linked bank account. This improves report reliability for all users.
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
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
Previously, a sign request scheduled for a later date would immediately appear on the portal for the signer. This fix corrects a technical issue where the system incorrectly displayed scheduled requests. Now, requests are only shown 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#118491This update ensures that fiscal categories and related products are automatically loaded when using the self-order blackbox feature. Previously, this process was inconsistent, leading to potential errors. 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 tax calculations within Point of Sale (POS) were consistently showing positive tax base amounts, regardless of the actual tax amount. This resulted in inaccurate tax reporting in the accounting system. The fix ensures that tax base amounts accurately reflect the tax liability, aligning POS transactions with financial reporting.
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 in German accounting reports incorrectly inherited datev code from the previous line. The fix ensures that untaxed lines now properly display an empty datev code, aligning with German tax regulations and improving the accuracy of Datev reports. This resolves a reporting discrepancy impacting financial data.
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 issue where DHL delivery confirmations were failing due to incorrect scheduled dates (past or missing). The system now automatically sets a future delivery date (one hour ahead) to prevent the error and ensure 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 being properly transmitted to the Peruvian EDI (SUNAT) documents when reversing invoices. Now, the credit note accurately reflects both the refund code and the user-provided cancellation explanation, ensuring compliance with Peruvian regulations. This improves data accuracy for financial reporting and audit trails.
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 data duplication and improving payment reconciliation accuracy. This resolves a previous bug impacting payment 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 footer message from invoices when the PEPPOL process isn't used, which was inappropriate for Business-to-Consumer (B2C) customers. The change ensures a cleaner and more professional invoice experience for B2C users. This improves clarity and aligns with customer communication standards.
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#268826 Forward-Port-Of: odoo/odoo#262412
This update significantly speeds up the process of adding and removing participants from marketing campaigns. By optimizing the underlying code, the sync time has been reduced from over 51 seconds to just 0.65 seconds, even with a large campaign of 115,000 participants. This improves campaign performance and responsiveness.
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 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
This change removes a test that was failing due to inconsistencies in how German date/time formats are handled by Chrome and the underlying Unicode CLDR data. The test was tied to a specific Chrome version and a recent update to the ICU library (which relies on CLDR) has introduced a conflict. This ensures the duration parsing functionality continues to work correctly across different Chrome versions.
Original PR description
Cause: ---------------------------------------- Commit 121806b57816d0fbd48b5538d2a8beae35905d99 added a test verifying that the duration in German is correctly recognized. In the test, "2 Std. 30…
Cause: ---------------------------------------- Commit 121806b57816d0fbd48b5538d2a8beae35905d99 added a test verifying that the duration in German is correctly recognized. In the test, "2 Std. 30 Min. 45 Sek.", was supposed to be recognized as 2.5125 hours. But on some browser versions it fails, as in the latest Chrome version. This is because we use `DurationFormat()` to get the localized units. This method is supported by all browsers and will use the browser's data to get the translations. This data comes from [Unicode CLDR](https://cldr.unicode.org/) which is updated regularly. We would need to change the test depending on the Chrome version, so we just delete it. It appears that for German hours the CLDR definitions have historically shifted between two distinct representations: "Std." and "h" As an example: - CLDR 47: https://github.com/unicode-org/cldr-json/blob/16f6b8578ba5fe98959034706f337674f816fc3f/cldr-json/cldr-units-full/main/de/units.json#L3526-L3527 - CLDR 48: https://github.com/unicode-org/cldr-json/blame/4d06be52b51bb2f75688d0abe55c52a66afed790/cldr-json/cldr-units-full/main/de/units.json#L3916-L3917 So the test fails in CLDR 48 but succeeds in CLDR 47. As the latest version of `ICU` (used by browsers) updates its dependency to CLDR 48 ([src](https://unicode-org.github.io/icu/download/78.html)) this explains why the latest Chrome version makes the test fail. runbot-939543
This update resolves a performance issue within the tests for the 'Discuss' feature. The change optimizes a database query, resulting in faster test execution times. This improvement ensures the stability and responsiveness of the Discuss functionality.
Original PR description
runbot-243772 https://github.com/odoo/enterprise/pull/119886
This update addresses a performance issue within the Odoo Discuss module, specifically related to counting data. The change optimizes a database query, resulting in faster response times and a smoother user experience. This improvement ensures the Discuss feature remains efficient and reliable for all users.
Original PR description
runbot-243772 https://github.com/odoo/odoo/pull/269111
This update fixes an issue where undoing the auto-plan feature would reset a shift's allocated workload hours, leading to inaccurate reporting. The change preserves the original workload value during undo, ensuring that shift allocations remain consistent and reliable. This improves the accuracy of resource planning.
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 fixes a login issue in Safari's private browsing mode, where users were unable to complete the turnstile challenge. The fix addresses a conflict between Safari's tracking protection settings and Odoo's form submission process. It ensures a stable login experience for Safari users in private browsing.
Original PR description
Scenario: - set up turnstile - with recent safari mac os or ios (reproduced from 26.2) go to /web/login page in a private window - enter login and password and pass the turnstile challenge - click on…
Scenario: - set up turnstile - with recent safari mac os or ios (reproduced from 26.2) go to /web/login page in a private window - enter login and password and pass the turnstile challenge - click on Log in Result: nothing happens and there is an error in the console "An invalid form control with name='' is not focusable." Cause: By default Safari has the Settings > Advanced > "Use advanced tracking and fingerprinting protection" set to "in Private Browsing". If this options is enabled in private browser or in all browsing, you can't login to Odoo with turnstile because safari is preventing the update of the element that is preventing to send the form: <input style="display: none;" class="turnstile_captcha_valid" required> When turnstile challenge succeeds, a value should be set to this input that will unlock the form, the .value property is updated but the browser Shadow Content is not (and if we remove display:none, the input is empty). Fix: I've not been able to reproduce the issue without turnstile using same situation and iframe. We don't know Safari heuristic but the unlocking is working if: - we use setProperty instead of .value - we unset required - we remove the input - we display the turnstile_captcha_valid input before challenge This fix replaces setting .value by setProperty, and add a failsafe of unsetting required. opw-5917286 fixes #247536 Forward-Port-Of: odoo/odoo#253367
This update resolves an issue that prevented attendee imports on events with the default mail scheduler. The fix ensures emails are queued instead of processed synchronously, preventing savepoint errors during the import process. This improves the reliability of attendee imports.
Original PR description
Importing attendees on an event that has an `after_sub` mail scheduler (the default on every event) fails with `savepoint "..." does not exist` and the import is aborted.…
Importing attendees on an event that has an `after_sub` mail scheduler (the default on every event) fails with `savepoint "..." does not exist` and the import is aborted. [`_update_mail_schedulers`](https://github.com/odoo/odoo/blob/b2f3270271f6/addons/event/models/event_registration.py#L298) runs the attendee scheduler synchronously on every registration create. The scheduler commits after each mail batch, which is fine from cron but problematic during an import: since [29460b723f49](https://github.com/odoo/odoo/commit/29460b723f49) [`load`](https://github.com/odoo/odoo/blob/b2f3270271f6/odoo/orm/models.py#L884) uses a single savepoint for the whole run, and any commit underneath releases it, so the next `ROLLBACK TO` / `RELEASE SAVEPOINT` raises `InvalidSavepointSpecification`. When `import_file` is in context, trigger the cron like the async path already does so the mails are queued instead of running inline. Steps to reproduce: 0. Have Contacts and Events installed 1. Events > Events, create a published event 2. Open the event, Attendees tab > Favorites > Import records 3. Upload a file with new attendees (Name, Email, no external id) 4. Click Import => "savepoint ... does not exist", import fails Ticket [link](https://www.odoo.com/odoo/project.task/6124741) opw-6124741 Forward-Port-Of: odoo/odoo#267586 Forward-Port-Of: odoo/odoo#260648
This update significantly speeds up the calculation of future leave balances by fixing a recursive process that was causing performance bottlenecks. The change eliminates unnecessary calculations, resulting in a 98% reduction in processing time for complex employee leave scenarios. This improves the responsiveness of the HR module.
Original PR description
## The Problem When computing a future leave balance, `_get_future_leaves_on` triggers `_process_accrual_plans`, which iterates period by period and calls `_get_leaves_taken` at each step.…
## The Problem When computing a future leave balance, `_get_future_leaves_on` triggers `_process_accrual_plans`, which iterates period by period and calls `_get_leaves_taken` at each step. `_get_leaves_taken` re-enters `_get_consumed_leaves` with `ignore_future=True`, but other accrual allocations on the same employee were not guarded by `precomputed_allocations`, causing `_get_future_leaves_on` to fire again for each of them, launching another full accrual run recursively. With N periods and K allocations, total work grew as $O(N^K)$. ## The Solution Adding `not ignore_future` to the guard prevents future projection in any nested context where it is both semantically incorrect and the source of the blowup. --- ## Benchmarks *Tested on a customer database with an employee having 2 accrual allocations and pending future leave requests 6 months out:* | | Queries | Request Time | Improvement | | :--- | :--- | :--- | :--- | | **Before** | 220K | 145.0s | — | | **After** | 2.7K | 2.8s | **-98%** | **Note:** More optimizations could be done to reduce the queries to a constant. However given the current design, it would be a bit big change and the current performance is already acceptable. **OPW-6115804** Forward-Port-Of: odoo/odoo#261172
This update removes a duplicate button from the channel management interface. Previously, users encountered errors when attempting to copy channels, and this feature offered little value. This change simplifies the channel creation process and resolves a technical issue.
Original PR description
duplicating channels does not provide much value. when you try to copy channel error comes like `you do not have enough rights to access the field ai_agent_id on Discussion Channel (discuss.channel).` now we are remove the duplicate button from channels form view cog menu as its does make sense to use it there at all. task-5494736 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269153 Forward-Port-Of: odoo/odoo#268999
This update corrects a bug in the sale details report that previously failed to include discounts applied through loyalty programs. Now, the report accurately displays the total discount amount, including those generated by the loyalty program, ensuring accurate sales reporting. This resolves an issue impacting all users utilizing the loyalty program.
Original PR description
When generating the sale details report, the number of discounts would not include the discount given by a loyalty program. The same problem applies for the total discount amount. Steps to reproduce: ------------------- * Create a loyalty program that gives a 10% discount automatically. * Open the PoS and make an order that activate the loyalty program. * Close the session and open the sale details report for this session. > Observation: The discount number and total is 0 opw-6185554 Forward-Port-Of: odoo/odoo#267753
This update addresses a traceback issue that appeared when viewing project calendars. The fix safely handles cases where the 'write_date' field is missing, preventing errors and ensuring the calendar view functions correctly. This resolves a minor instability in the Project app.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install Studio and Project app with demo 2. Go to Project App > studio > views > enable calendar view > close studio 3. Click on any…
Steps to reproduce:
---------------------------------------
1. Install Studio and Project app with demo
2. Go to Project App > studio > views > enable calendar view > close studio
3. Click on any project
Observation:
---------------------------------------
A traceback appears:
```
Caused by: TypeError: Cannot read properties of undefined (reading 'toMillis')
at get uniqueId (http://localhost:8192/web/assets/cbd2032/web.assets_web.min.js:21370:74)
at Many2OneAvatarEmployeeField.template (eval at compile (http://localhost:8192/web/assets/cbd2032/web.assets_web.min.js:1387:421), <anonymous>:25:122)
```
Issue:
---------------------------------------
The traceback is yielded from the `get uniqueId` getter from the `Many2OneAvatarUserField` component:
https://github.com/odoo/odoo/blob/be8b1bbad757fda27df579ce36cbc97324f58f62/addons/mail/static/src/views/web/fields/many2one_avatar_user_field/many2one_avatar_user_field.js#L48-L50
where `write_date` is undefined. This getter was added by, https://github.com/odoo/odoo/commit/3732ca85b03bea9eabfb05cc306ce0bf5bac88d4#diff-94c14c7d2a5fe89c7558f5dffbd6cd126bcba0b140e821ef317f25ac15eb9352 which handled the case of undefined `write_date` for the related Kanban component
https://github.com/odoo/odoo/blob/c3172d65db44c41f5619aef20532c3846494ea0e/addons/hr/static/src/views/fields/many2one_avatar_employee_field/kanban_many2one_avatar_employee_field.js#L49-L52
For the Kanban record for User Avatar, a similar solution is applied in this problematic getter. https://github.com/odoo/odoo/pull/251000/changes/80b5e529304ad9a0bdaf55a49e64ac8097a0380a
Solution:
---------------------------------------
Handle missing `write_date` safely using optional chaining to avoid undefined errors
Similar fix applied for the employee avatar in https://github.com/odoo/odoo/pull/260069/changes/6658b41310106bb4e425ae537a1af6a8ed71f864
Note:
---------------------------------------
For `saas-19.3` It is solved in commit https://github.com/odoo/odoo/commit/8847084c14ae4e0595eed7e006c58e161ce450ea
opw-6210249This update resolves an issue where a specific configuration in the French VAT reporting module incorrectly generated an error. When the street address was short and 'street 2' was not used, the system produced invalid XML data. This fix ensures accurate report generation and prevents potential disruptions to the VAT reporting process.
Original PR description
When the street field is shorter than 30 char and street 2 is false, we end up with " False" in the xml, which will return an error in aspone. no task id Forward-Port-Of: odoo/enterprise#119718
This update fixes a potential problem where users could accidentally trigger mass email campaigns bypassing intended filters. The change prevents users from directly retrying failed emails linked to marketing automation campaigns, reducing the risk of unintended spam and ensuring targeted email delivery. A user interface change hides the 'Retry' button to avoid this.
Original PR description
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing…
When a mailing is managed by a marketing automation campaign, its target domain is dynamically handled by the campaign's activities. If a user clicks the "Retry" button directly on the mailing template, it bypasses the campaign filters and queues the mailing for the entire target model, causing unintended mass spam. This commit fixes the issue by: 1. Raising a UserError in `action_retry_failed` if the mailing is linked to marketing automation (`use_in_marketing_automation`). 2. Hiding the "Retry" button in the frontend view to prevent confusion. 3. Adding a unit test to ensure this edge case is caught in the future. Steps to reproduce: 1. Create a marketing campaign with a filter and an email activity. 2. Run the activity and ensure at least one email trace fails. 3. Open the mailing template via the "Templates" smart button. 4. Click the "Retry" button on the template form. 5. The mailing is placed in the standard queue, bypassing the domain and targeting all records of the underlying model. OPW-6220106 Forward-Port-Of: odoo/enterprise#119597 Forward-Port-Of: odoo/enterprise#118759
This update resolves a sporadic test failure related to highlighting the timesheet timer field. The change replaces a temporary workaround with a more reliable method using React's useEffect hook, ensuring consistent test results and improved stability.
Original PR description
This PR replaces the macrotask hack to hightlight the content of the timer field on focus with a more idiomatic useEffect. This ensures the corresponding test won't fail randomly if the macrotask queue happens to not be cleared before we check the highlight.
This update corrects a technical error within the Odoo Enterprise planning module. The issue stemmed from how default values were retrieved, which could result in an error when multiple planning slots were accessed simultaneously. This fix ensures the system functions reliably and prevents potential disruptions to planning processes.
Original PR description
`self` could be non-singletion recordset ``` (Pdb) p self.default_get(['repeat_interval']) *** ValueError: Expected singleton: planning.slot(227, 174) ``` See: 689a15b46c85774f3ab9ee4b9173a549c2ce1abf
This update addresses a recurring problem where payments at self-order kiosks were getting stuck when using the IoT Worldline terminal. The fix allows the system to correctly handle terminal disconnections and provides more specific error messages based on the terminal's feedback, improving the overall payment experience. This prevents frustrating delays for customers.
Original PR description
This PR fixes some payments in pos kiosk being stuck with iot worldline terminal. It allows to succesfully interpret when the terminal is disconnected and adapts the error messages to the information received fromthe terminal instead of the current generic "An error has occurred" enterprise: https://github.com/odoo/enterprise/pull/107709 task-5946033 Forward-Port-Of: odoo/odoo#249582 Forward-Port-Of: odoo/odoo#249101
This update significantly speeds up the Inventory Valuation report by reducing the number of products processed. Previously, the report strained system resources, but now it focuses only on products with stock, dramatically improving performance – particularly for large catalogs. This change ensures the report runs efficiently and reliably.
Original PR description
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only…
Opening the Inventory Valuation report iterated every storable product to compute total_value, which on large catalogs used several GB of RAM and timed out workers. The report now searches only products that have stock (under the same valuation context that total_value uses) or that are lot-valuated, and feeds that smaller set into stock_value and stock_accounting_value. For historical (at_date) reports the search runs with to_date in context so qty_available is scoped to that date. _get_accounts_by_product() also switches to search_fetch so only categ_id is loaded upfront. Benchmarks were measured on a customer database restore with ~360k storable products. After filtering, ~2.5k products feed into the valuation today and ~2.2k for a historical date. Benchmark opening Inventory Valuation report (Accounting) | Date | Before | After | Speed up | |------------|--------|--------|----------| | Today | ~88s | ~2s | 41x | | Historical | ~245s | ~173s | 1.4x | The historical improvement is more modest because stock_value still has to compute total_value at the historical date for the remaining products, which traces SVL/stock.move history; the filter eliminates the dominant per-product overhead today but only the tail in the historical case. 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#265931 Forward-Port-Of: odoo/odoo#254010
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 setup, ensuring a subscription plan is present before allowing the recurring product to be added, improving order stability.
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#119955 Forward-Port-Of: odoo/enterprise#107691
This update corrects a bug where products without lot/serial tracking incorrectly displayed expiration warnings. The change ensures that products tracked by quantity don't trigger the expiration flow, aligning with intended usage. This prevents unnecessary alerts and streamlines product management.
Original PR description
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup…
A product can have expiration date (use_expiration_date) enabled after being changed from lot/serial tracking to no tracking (quantity). The issue this causes is that it can open the expiration popup since from saas-18.4 there is a line where if `ml.removal_date <= datetime.datetime.now()` the picking is expired. So, if the product previously met these conditions, it will still be able to enter this flow. And since this product doesn't use a lot_id it displays “You are going to deliver the product False, False which is expired or should at least be removed from stock” What should happen: When a product is not tracked, use_expiration_date should be False as expiration dates are intended to be managed through lots or serial numbers. Steps to reproduce 1. Enable Product Expiry. 2. Create a storable product with: - Tracking: By Lots - Use Expiration Date: enabled - Set a value greater than 0 for removal_time 3. Change the product tracking to By Quantity. 4. Create and validate a receipt for the product. Related Tickets: opw-6255673 Forward-Port-Of: odoo/odoo#268135
This update corrects a technical issue with how Odoo validates cardholder addresses for Stripe payments. The system was incorrectly using an outdated ISO 3166-2 standard for state codes, causing failures for US addresses. This fix ensures accurate address validation and avoids potential payment processing problems.
Original PR description
Stripe says that address.state is "State, county, province, or region (ISO 3166-2)". There didn't seems to be any issues since it seems that it's not checked for the EU. However, this is still wrong and could raise an issue if Stripe decide to start checking them. Also, with the US coming soon, it's being checked and failed. Forward-Port-Of: odoo/enterprise#114480
This update corrects a bug in how leads are assigned to sales teams, ensuring a more equitable distribution of leads. Previously, team members created earlier received a disproportionate number of leads, particularly when quotas were equal. The fix introduces random tie-breaking to prevent this bias and ensure fair lead assignment.
Original PR description
_assign_and_convert_leads() is biased towards team members created earlier because they're ordered by create_date, id. When members have equal quota, the round-robin order falls back to the order of the team members. If the amount of leads distributed across the team is not a multiple of the team size, then the oldest members will get more leads assigned. This advantage repeats each time the cron runs and can add up to a big difference, the provided test case ends up assigning all 30 leads to the more senior member without the fix. Note that the lead_day_count field used in _get_assignment_quota() doesn't solve the problem. It helps to balance leads assigned in the same 24 hour window, but because the same senior person always goes first inside one of those windows, they will always get more leads assigned to them. To fix it we break ties in the quota randomly. task-6119168 Forward-Port-Of: odoo/odoo#268716 Forward-Port-Of: odoo/odoo#259775