Daily updates from Odoo
Wednesday, August 19, 2026
285 changes
13 changes
Enhancements to existing features
The default waiting time for certain web interface test checks has been increased from a very short window to 10 seconds. This reduces false test failures on busy machines without slowing successful test runs, improving confidence in automated quality checks.
Original PR description
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests…
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests give 10 seconds. 430 call sites in addons reach these three helpers and 29 pass an explicit timeout, so 12 frames is what the other 401 get. The problem is that 12 frames is less than what the client needs on a loaded machine. Measured on "should remove file from html editor if removed from attachment list", on the wait that follows the Full composer button: - 5 to 7 frames on an idle machine; - 11 to 18 frames over 8 runs with the machine at load 10 to 20, 5 of the 8 above the 12 frames the default allows. Those 5 are failing runs, and the same test at load 13 to 29 fails 6 runs out of 6 with the 200 milliseconds, 0 out of 6 with 10 seconds. Note that a longer timeout costs nothing on a green build: the wait ends on the frame the DOM matches, so it only delays the report of a test that was going to fail anyway. Hoot fails the test itself after 5 seconds, 15 in test_js.py, which keeps bounding a wait that never resolves. This commit raises the default to 10 seconds, the delay a tour step already gets in macro.js and the one contains() and expect.waitForSteps already have. https://runbot.odoo.com/odoo/error/946094 Forward-Port-Of: odoo/odoo#282702
Online shoppers can now select multiple values within the same product filter, such as choosing both Lenovo and HP while also filtering by storage size. This supports broader product searches and avoids unnecessary filter refreshes, making browsing more flexible and efficient.
Original PR description
Filters are now completely exclusive, which prevent 0 results but also prevents more "open" searches as "Lenovo" OR "HP" AND "512GB SSD". Stop updating the filters based on selected attribute values to avoid the extra product query and allow selecting non exclusive filters from the same attribute. task-6341310 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273076
The update schedule for IoT boxes no longer runs on weekends. This helps ensure updates happen during support hours, reducing the risk of issues when help may be less available.
Original PR description
This PR removes weekend days from dynamic update for the iot boxes. This allows to follow the support availabilities Forward-Port-Of: odoo/odoo#282780
Resolved issues and error corrections
Generated ISO 20022 payment files now include the state/province and second address line when available on vendor or employee addresses. This helps avoid bank rejections, especially for North American wire transfers that require complete beneficiary address details.
Original PR description
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street…
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street complement (suite, unit, ...) therefore never appear in the generated file, even when they are set on the partner, and there is no way to fix it from the record. Some North American banks reject wire transfers whose beneficiary address lacks the state/province, so those payments fail regardless of how complete the vendor record is. Return the state code and street2 alongside the other address components, from the partner for the base implementation and from the employee private address for the hr one, so the payment engine can write them in the PstlAdr block. Steps to reproduce: - Install Accounting and enable a generic ISO 20022 payment method on a bank journal - Create a vendor located in the US or Canada with a complete address, including the state and a second street line - Register a vendor payment, add it to a batch and generate the pain.001 file - The creditor PstlAdr has no state/province, and its street line only carries the first street field: the street2 part is dropped Companion enterprise PR emitting the state in the generated file: odoo/enterprise#127958 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282620 Forward-Port-Of: odoo/odoo#282518
Point of Sale now avoids creating extra positive and negative down payment lines when taking a down payment on a sales order that already has one. This keeps POS orders clearer and prevents confusing duplicate payment adjustments for staff and customers.
Original PR description
When making a downpayment in the PoS on a sale order that already contained another downpayment, there would be multiple downpayment lines created in the PoS order (1 positive and 1 negative). Steps to reproduce: ------------------- * Create a sale order in the sales app * Make a downpayment in the sales app * Open the PoS and make a downpayment on the same sale order > Observation: Two lines are added to the order, 1 negative and 1 positive Why the fix: ------------ When creating the baseLines for the downpayment we should not consider the previous downpayments and only consider the other lines. opw-6354823 Forward-Port-Of: odoo/odoo#281397 Forward-Port-Of: odoo/odoo#275653
When a production order was already confirmed, updating its bill of materials could leave outdated manufacturing steps in place or fail to reflect changes. This fix ensures confirmed orders stay aligned with the latest bill of materials so production instructions remain accurate.
Original PR description
### Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first…
### Steps to reproduce: - Create a product with a bom and 2 operations - Create an MO for 1 unit of that product - Confirm the MO - On the bom, delete the second operation and modify the first operation on anything else than the company, name or workcenter - Go back to the MO, click the "Update Bom" button > The second operation is not unlinked and the first operation is not updated ### Cause of the issue: The `action_update_bom` updates the move raws and operations of the MO via the `_link_bom`: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L1214-L1218 For draft MO's all the work of these updates is done via the compute methods and by deleting all the records unrelevant to the new bom: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2603-L2626 And, in that case all the workorders that are not linked to an operation of the bom are expected to be deleted. However, when the MO is not in draft, the update of operations is expected to be performed here: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2647-L2664 However, since the operation of the bom has been deleted, the workorder that is expected to be deleted is not linked to any operation and hence does not satisfy the condition to be deleted: https://github.com/odoo/odoo/blob/f66614193cce18f5a3298d03ce7e5f29d54f07e9/addons/mrp/models/mrp_production.py#L2663-L2664 Concerning the non update of operations, it happens because the MO's operation are only updated on the three fields: `company_id`, `workcenter_id`, `name`: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/mrp/models/mrp_production.py#L2647-L2664 https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/mrp/models/mrp_production.py#L2628-L2629 However, many other changes can and are actually relevant. ### Note: Prior to commit 80e6ed658fb43584bc2fad673ca40d9af6cf0ab6 operations were archived on boms rather than deleted: https://github.com/odoo/odoo/blob/4a5270218fe6fd7d30edb6d684b3340dc7423bab/addons/mrp/views/mrp_routing_views.xml#L53-L55 As such they would still be linked to an operation (but unrelated to the present values of the bom) and hence would fall into the condition of being unlinked from the MO. Since the bom operations are no longer archived there is no way to determine if an operation used to be linked to a bom and we therefore need to chose between deleting all operations unrelated to the present bom or to keep them all (when the MO has been confirmed). Enterprise: https://github.com/odoo/enterprise/pull/120709 opw-6285878 opw-6261738 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280803 Forward-Port-Of: odoo/odoo#269747
When a combo meal is split into individual items, each item is now placed under its correct course automatically. If all items from a course are removed, that course is removed too, helping keep restaurant orders clear and accurate.
Original PR description
Following this commit: ==== - When a combo is broken down, its items are assigned to their respective courses. - Remove a course when all its items are deleted from the cart. task-6121521 Forward-Port-Of: odoo/odoo#282255 Forward-Port-Of: odoo/odoo#260276
Refunds through Authorize.net now correctly handle both card and ACH/eCheck payments. This fixes a case where refunds could fail after settlement, helping businesses process returns without manual support or delays.
Original PR description
**Steps to reproduce:** 1. Install Sales and payment_authorize modules 2. Enable "Online Payment" in the settings and Configure the payment method to be Authorize.net 3. Create a sale order, confirm…
**Steps to reproduce:** 1. Install Sales and payment_authorize modules 2. Enable "Online Payment" in the settings and Configure the payment method to be Authorize.net 3. Create a sale order, confirm it and create the invoice 4. Pay the invoice with an eCheck (ACH) payment method through the Authorize.net provider 5. Wait for the payment to be settled by Authorize.net (_around 24 hours_) 6. Initiate a refund of the payment **Issue:** The refund fails with error `E00003: "The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardNumber' element is invalid - The value XX is invalid according to its datatype 'String' - The actual length is less than the MinLength value` **Expected behavior:** The refund should be processed successfully regardless of whether the original payment was made by credit card or eCheck (ACH) **Why this happens:** - The `refund()` method in `AuthorizeAPI` builds the refund request using a `creditCard` payment payload - When the original transaction was an ACH/eCheck payment, the `creditCard` key is absent from the transaction details returned by Authorize.net - The resulting request is rejected by Authorize.net because it does not satisfy the minimum length constraint for `cardNumber` **Fix:** - Detects whether the original payment used `creditCard` or `bankAccount` from the transaction details and build the appropriate payload according to Authorize.net API documentation: https://developer.authorize.net/api/reference/index.html#payment-transactions-credit-a-bank-account opw-6359726 Forward-Port-Of: odoo/odoo#282810 Forward-Port-Of: odoo/odoo#277742
When users clicked a suggestion in the message composer, the system could sometimes keep the typed search text instead of inserting the chosen name. This fix ensures the suggestion shown on screen is the one selected, making mentions and similar autocomplete actions more reliable.
Original PR description
Before this commit, clicking a composer suggestion could leave the composer with the typed search instead of the selected name, as in the test "Mention a partner with special character (e.g. apostrophe ')" on runbot: Failed to find 1 of ".o-mail-Composer-input" with value "..." (Timeout of 10 seconds). Found 0 instead. This happens because NavigableList looks up the clicked option by index in its current props, while the item clicked comes from the last render. Typing "@" lists the two members of the channel and typing "Pyn" drops one of them: owl assigns the filtered options one frame before it patches the list, so a click in between looks up index 1 in a list of one option, finds nothing and returns. This commit passes the rendered option to the click handler, keeping the index lookup as a fallback so that the signature stays the same on a stable version. https://runbot.odoo.com/odoo/error/946154 Forward-Port-Of: odoo/odoo#282897
This change prevents the Point of Sale sample products from failing to load in setups where product attributes were removed or demo data is not present. It ensures the required attribute data is available first, so opening a new shop and loading sample items works reliably.
Original PR description
## Steps to Reproduce: 1. Install the **PoS** and **Sales** modules without demo data. 2. Settings > Enable **Variants**. 3. Sales > Products > Attributes > Delete "**Brand**" attribute. 4. Create a **Clothes Shop** and open the register. 5. Load the **Sample** products. ## Error: `ParseError - while parsing /home/odoo/src/odoo/saas-19.4/addons/product/data/product_attribute_demo.xml:5, somewhere inside...` ## Cause: The `product_attribute_demo.xml` file references attributes that do not exist when the demo data is loaded, which raises an error. Before 19.4, the attributes were defined in the same file. After this commit https://github.com/odoo/odoo/commit/56942bcf34785e869c7648cf100c8818c5da0b6d, the attributes are defined separately in the `product_attribute_data.xml` file. ## Fix: This commit loads the data file before, ensure the referenced attributes are available when the demo file is processed. sentry-7640019804
This fix ensures electronic invoices use the correct tax category when a company in or outside the EEA bills a customer across borders. It prevents invoices from being labeled as exempt when they should be treated as export or reverse-charge cases, reducing the risk of incorrect e-invoice submissions.
Original PR description
### Issue before this commit: When generating an electronic invoice (e.g., ZUGFeRD/Factur-X) with a 0% tax from a non-EEA supplier (e.g., Switzerland) to an EEA customer (e.g., Germany), the XML tax…
### Issue before this commit: When generating an electronic invoice (e.g., ZUGFeRD/Factur-X) with a 0% tax from a non-EEA supplier (e.g., Switzerland) to an EEA customer (e.g., Germany), the XML tax <ram:CategoryCode> is incorrectly set to 'E' (Exempt) instead of 'G' (Export). ### Steps to reproduce the issue: 1. Download Accounting and l10n_ch 2. Set the VAT for the CH company 3. Create an invoice for a German customer with 0% tax setted (for which you have to set as electronic invoicing the ZUGFeRD template into the Accounting tab of his contact) 4. Send it and see that the tag <ram:CategoryCode> is setted as E instead of G ### Cause of the issue: The logic assigning the 'G' and 'K' tax category codes was only triggered if the supplier was located within the EEA. If the supplier was outside the EEA, the code bypassed this block entirely and fell back to the default 'E' code for 0% taxes. ### Reason to introduce the fix: Update the condition to trigger when either the supplier or the customer is in the EEA. This ensures that cross-border transactions involving at least one EEA party correctly evaluate and apply the 'G' (Export outside the EU) category code. Also the case supplier not in eea with VAT filled in + customer in eea + RC tax with amount != 0 is fixed now (letter G reported instead of S). ### Documentation: [eInvoicing technical guidance document_v1.pdf](https://github.com/user-attachments/files/30831749/eInvoicing.technical.guidance.document_v1.pdf) opw-6407399 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282904 Forward-Port-Of: odoo/odoo#281245
When a sales order uses a fiscal position, advance payment invoices now use the account mapping defined by that fiscal position. This fixes cases where down payment invoices could post to the wrong account, helping ensure invoices and accounting entries follow the company’s tax/accounting rules.
Original PR description
How to reproduce: - In a Fiscal Position, map the Downpayment account set in the settings to anything else - Put that Fiscal Position on a SO. - On that SO, create a Downpayment invoice -> The regular Downpayment account is used on the Downpayment invoice, but it should have been mapped because of the Fiscal Position account mapping Solution: Pre-map the company's default down payment account using the Sales Order's Fiscal Position before passing it to the invoice line creation. This ensures the correct account mapping is always respected for advance payment invoices. Task-6212218 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281507 Forward-Port-Of: odoo/odoo#279464
When a subcontracted product is returned for exchange, the replacement items now go to warehouse stock instead of staying in the subcontracting location. The received quantity on the purchase order is also updated correctly, so the order reflects the full amount delivered.
Original PR description
Steps to reproduce ------------------ 1. Configure a product with a subcontracted BoM and a subcontractor. 2. Create a purchase order of 10 units for that product and confirm it. 3. Receive the 10…
Steps to reproduce ------------------ 1. Configure a product with a subcontracted BoM and a subcontractor. 2. Create a purchase order of 10 units for that product and confirm it. 3. Receive the 10 units. 4. On the receipt, use "Return for Exchange" on 3 units and validate both the return and the exchange receipt. Issue ----- After the exchange, the 3 units stay in the subcontracting location instead of reaching `WH/Stock`, and the received quantity on the purchase order line stays at 7 instead of 10. `mrp_subcontracting` overrides `_prepare_move_default_values` to force the move `location_dest_id` to the subcontractor location for every `is_subcontract` move: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/mrp_subcontracting/wizard/stock_picking_return.py#L20-L25 That is correct for the return, but the same override also runs for the exchange re-receipt, an `incoming` picking whose destination should be the stock location from `return_type.default_location_dest_id`: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/stock/wizard/stock_picking_return.py#L137-L153 The exchange move then goes from the subcontracting location back to itself, so validating it nets zero and `WH/Stock` never receives the units. Skipping the override when `new_picking.picking_type_id.code` is `incoming` lets the exchange land in stock. The received quantity must also count that receipt. `_should_count_for_quantity_received` only counts `supplier` or `transit` sources: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/stock/models/stock_move.py#L330-L331 so the exchange, sourced from the internal subcontracting location, is skipped while the return still subtracts its quantity. Counting subcontracting-sourced moves: https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/addons/mrp_subcontracting/models/stock_move.py#L312-L314 restores `qty_received` to 10. opw-6410978 Forward-Port-Of: odoo/odoo#282666 Forward-Port-Of: odoo/odoo#279431
12 changes
Enhancements to existing features
The default waiting time for web interface test checks has been increased so tests are less likely to fail on busy machines. This improves the reliability of development and release validation without slowing successful test runs.
Original PR description
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests…
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests give 10 seconds. 430 call sites in addons reach these three helpers and 29 pass an explicit timeout, so 12 frames is what the other 401 get. The problem is that 12 frames is less than what the client needs on a loaded machine. Measured on "should remove file from html editor if removed from attachment list", on the wait that follows the Full composer button: - 5 to 7 frames on an idle machine; - 11 to 18 frames over 8 runs with the machine at load 10 to 20, 5 of the 8 above the 12 frames the default allows. Those 5 are failing runs, and the same test at load 13 to 29 fails 6 runs out of 6 with the 200 milliseconds, 0 out of 6 with 10 seconds. Note that a longer timeout costs nothing on a green build: the wait ends on the frame the DOM matches, so it only delays the report of a test that was going to fail anyway. Hoot fails the test itself after 5 seconds, 15 in test_js.py, which keeps bounding a wait that never resolves. This commit raises the default to 10 seconds, the delay a tour step already gets in macro.js and the one contains() and expect.waitForSteps already have. https://runbot.odoo.com/odoo/error/946094 Forward-Port-Of: odoo/odoo#282702
The Time Off configuration now displays the option to create a Calendar meeting when a leave request is approved. This makes the setting easier to find and helps teams control whether absences also appear in the Calendar app.
Original PR description
The `create_calendar_meeting` field on `hr.leave.type` allows users to choose if leave requests created with a given time off type generate a corresponding entry in the Calendar app. However, this field was not displayed on the form view. This commit adds `create_calendar_meeting` to the `hr.leave.type` form view inside the configuration section, along with dedicated help text explaining its behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282698 Forward-Port-Of: odoo/odoo#280593
Resolved issues and error corrections
Payment files now include the state or province and second address line from vendor or employee address records. This helps prevent bank transfer rejections, especially in countries like the US and Canada where state or province details are often required.
Original PR description
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street…
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street complement (suite, unit, ...) therefore never appear in the generated file, even when they are set on the partner, and there is no way to fix it from the record. Some North American banks reject wire transfers whose beneficiary address lacks the state/province, so those payments fail regardless of how complete the vendor record is. Return the state code and street2 alongside the other address components, from the partner for the base implementation and from the employee private address for the hr one, so the payment engine can write them in the PstlAdr block. Steps to reproduce: - Install Accounting and enable a generic ISO 20022 payment method on a bank journal - Create a vendor located in the US or Canada with a complete address, including the state and a second street line - Register a vendor payment, add it to a batch and generate the pain.001 file - The creditor PstlAdr has no state/province, and its street line only carries the first street field: the street2 part is dropped Companion enterprise PR emitting the state in the generated file: odoo/enterprise#127958 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282620 Forward-Port-Of: odoo/odoo#282518
This fixes several point-of-sale payment issues caused by an earlier internal renaming. It restores proper handling for Mercado Pago, Cashdro, Cashmatic, Safaricom, and bank QR payments so transactions do not remain stuck or fail to complete.
Original PR description
*: point_of_sale,pos_mercado_pago,pos_cashdro,pos_cashmatic, pos_safaricom d7a627160372 renamed the client-side payment interface attached to a pos.payment.method from `payment_terminal` to `payment_interface`, moved integrations off `payment_method_type` onto `payment_provider`, and renamed the `qr_code` type to `bank_qr_code`. Several call sites were left behind and now read attributes or compare against values that no longer exist, so they silently never match. Mercado Pago calls a method straight off the missing attribute, so an incoming webhook raises a TypeError and the payment line stays pending forever. The rest degrade silently: Cashdro and Cashmatic never cancel on Force Done, Safaricom never resolves the payment promise, and Bank QR lines left in `waiting` are no longer reset to `retry` when the session restarts, leaving them stuck. Use the existing `useBankQrCode` getter for the type check rather than repeating the literal. opw-6372208
The website editor now shows dynamic snippet filter names in the editor user's preferred language instead of the website's default language. This prevents confusion for editors working on multilingual websites where the public site language differs from their own interface language.
Original PR description
Steps to reproduce: 1. In an `en_US` database, install the Arabic (`ar_001`) language and set it as the website's default language. 2. Add a `blog.post` dynamic snippet to a page and select it. 3. Open the snippet options. 4. Notice that the Filter dropdown is displayed in Arabic instead of English. The RPC fetching the available snippet filters targets the `website=True` `/website/snippet/options_filters` route. During the request initialization, website routes inherit the frontend request language (see: `frontend_pre_dispatch()`), so the ORM context lang is set to the website language. As a result, translated fields such as name are read in that language. Force `request.env.user.lang` in the context when fetching the filters since their names should be displayed in the editor's preferred language. task-5979540 Forward-Port-Of: odoo/odoo#280743 Forward-Port-Of: odoo/odoo#275390
Store pickup locations are no longer shown as selectable delivery addresses during checkout. This prevents shoppers from accidentally choosing an internal pickup-point record instead of their own delivery address, keeping the checkout flow clearer and less error-prone.
Original PR description
Steps to produce: --- - Install `website_sale_collect` module. - Create and publish a product. - Add it to the cart and proceed to checkout. - Fill in the address and confirm. - Select a `pick-up in…
Steps to produce: --- - Install `website_sale_collect` module. - Create and publish a product. - Add it to the cart and proceed to checkout. - Fill in the address and confirm. - Select a `pick-up in store` delivery method. - Click the edit icon on the contact details. - Confirm without making any changes. Issue: --- - The pick-up point address appears as a selectable delivery address in the contact details list, which it should not. Root cause: --- - When a pick-up point is selected, `set_pickup_location` calls `_address_from_json` ([1]), which creates a child `res.partner` record with `type='delivery'` and sets `pickup_delivery_method_id` to identify it as a pick-up point address. Later, when the user returns to the address page, `_prepare_address_data` calls `_get_delivery_address_domain` ([2]) from `portal`. This method returns all child partners with `type='delivery'` without distinguishing between user-created delivery addresses and the auto-generated pick-up point addresses As a result, the pick-up point address incorrectly appears in the checkout address list. Solution: --- - As specified in [task], partners created through this flow should be archived. However, in the referenced [commit], the `active=False` flag was removed when creating the partner, causing newly created partners to remain active. Override `_get_delivery_address_domain` to exclude pick-up point addresses. Since auto-generated pick-up point addresses always have `pickup_delivery_method_id` set, they are filtered out from the checkout address list, while manually created delivery addresses remain unaffected. [1]https://github.com/odoo/odoo/blob/fb6298e50a7c8ded2800254e8715336eeb37deb5/addons/website_sale_stock/models/res_partner.py#L16-L72 [2]https://github.com/odoo/odoo/blob/fb6298e50a7c8ded2800254e8715336eeb37deb5/addons/portal/models/res_partner.py#L51-L55 [task]: https://www.odoo.com/odoo/project/49/tasks/3645144 [commit]: https://github.com/odoo/odoo/commit/fb74a371407ee19c6b1a3ab9f5a7b314978cb5cb opw-6356778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
DIN 5008 business documents now show dates in the expected German, Austrian, and Swiss format regardless of the user’s language settings. Company footers also use the appropriate country-aware commercial register label, avoiding misleading German-specific text for Austrian and Swiss companies.
Original PR description
* = de, din5008, din5008_purchase, din5008_repair, din5008_sale **Steps to reproduce:** * Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`) * Set the document…
* = de, din5008, din5008_purchase, din5008_repair, din5008_sale
**Steps to reproduce:**
* Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`)
* Set the document layout to **DIN 5008** and generate any PDF report (invoice, quotation, purchase order, etc.).
**Observed behavior (date format):**
* All dates in the information block (Invoice Date, Due Date, Delivery Date, Order Date, etc.) are rendered in `yyyy-mm-dd` format instead of the expected `dd.MM.yyyy` format used in DE, AT, and CH.
**Observed behavior (commercial register):**
* The footer always shows `HRB-Nr.:` regardless of whether the company has a commercial register entry.
* The abbreviation `HRB-Nr.:` appears even for Austrian and Swiss companies, where the commercial register number is a German-specific concept.
* In the company form view, the field is labeled generically as "Company ID" instead of "Commercial Register Number" for German companies.
**Cause (date format):**
* All `t-options="{'widget': 'date'}"` directives across the DIN 5008 template family rely on the active user's language locale for date formatting. If the user language is not `de_DE`, dates render in the locale's default format (e.g. `yyyy-mm-dd` for `en_US`).
**Cause (commercial register):**
* The footer renders `company.company_registry` unconditionally with no country guard and no label.
**Fix (date format):**
* Add `'format': 'dd.MM.yyyy'` explicitly to all `t-options` date widgets across all DIN 5008 report templates (`l10n_din5008`, `l10n_din5008_sale`, `l10n_din5008_purchase`, `l10n_din5008_sale_subscription`, `l10n_din5008_repair`, `l10n_din5008_account_followup`, `l10n_din5008_industry_fsm`).
* This is correct for all three countries using DIN 5008 (DE, AT, CH), which all follow the `dd.MM.yyyy` convention.
**Fix (commercial register):**
* Remove the hardcoded `HRB-Nr.:` label from the footer and instead render `company.partner_id.company_registry_label` (which is country-aware).
* Update the duplicate contact warning message to use the country-aware label via `company.partner_id.company_registry_label`, backed by a new `_get_company_registry_labels` override in l10n_de that registers `Commercial Register Number` for `DE`.
* In the company form view (`l10n_de`), hide the generic "Company ID" field for German companies and show a relabeled instance with `string="Commercial Register Number"` instead.
opw-6392649
Forward-Port-Of: odoo/odoo#282964
Forward-Port-Of: odoo/odoo#279085This update makes the product variant setting available when only Point of Sale is installed. It ensures businesses on the OAF plan can access the same variant option seen in other areas, so the setup matches expected behavior and can be configured when needed.
Original PR description
If only PoS is installed (if you are on the OAF plan). The variants settings is unavailable and cannot be activated. Steps to reproduce: ------------------- * Install only PoS * Look for variant in settings > Observation: The option is not showing up Why the fix: ------------ The setting is just a copy of the other places where the settings is available. opw-6378568
This change corrects how self-order validates combo products, making sure each combo item is linked to the right parent combo line. It prevents incorrect combinations from being accepted and helps avoid order entry mistakes for customers using self-order kiosks.
Original PR description
Be sure that combo product of the current line belong to its combo parent line. Forward-Port-Of: odoo/odoo#282809 Forward-Port-Of: odoo/odoo#281741
Fixed an issue where clicking a suggested mention could keep the typed search text instead of inserting the selected name. This makes mention and autocomplete selections more reliable, especially when the list changes quickly while typing.
Original PR description
Before this commit, clicking a composer suggestion could leave the composer with the typed search instead of the selected name, as in the test "Mention a partner with special character (e.g. apostrophe ')" on runbot: Failed to find 1 of ".o-mail-Composer-input" with value "..." (Timeout of 10 seconds). Found 0 instead. This happens because NavigableList looks up the clicked option by index in its current props, while the item clicked comes from the last render. Typing "@" lists the two members of the channel and typing "Pyn" drops one of them: owl assigns the filtered options one frame before it patches the list, so a click in between looks up index 1 in a list of one option, finds nothing and returns. This commit passes the rendered option to the click handler, keeping the index lookup as a fallback so that the signature stays the same on a stable version. https://runbot.odoo.com/odoo/error/946154 Forward-Port-Of: odoo/odoo#282897
The shop now uses the same searchable product fields for both result matching and filter counts. This avoids cases where hidden HTML or technical text caused too many products to be processed, making search and filters more reliable for shoppers.
Original PR description
The `/shop` product results and facets use different search fields. In particular, facets search raw `website_description` HTML, causing terms such as `weight` to match CSS like `font-weight` and process far more products than are displayed. Use one shared field list for both paths: - `name` - `variants_default_code` - `description_sale` - `description_ecommerce` Stop searching `default_code`, internal `description`, and raw `website_description`. opw-6391984 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280720
This change makes an automated image upload test more reliable by giving it a little more time to detect the uploaded image. It helps prevent random test failures on slower or heavily used systems, improving overall build stability.
Original PR description
Before this commit, this image field test sometimes failed because it could not find the image that had just been uploaded. Similarly to [1], we increase the waitFor timeout to 1s. Indeed, uploading an image can take time, and with high CPU usage, it could happen that the default 200ms delay wasn't enough. [1] https://github.com/odoo/odoo/pull/168196 runbot error-242406 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#281200
7 changes
Enhancements to existing features
The Point of Sale no longer waits for receipt printing to finish before completing order validation. This makes checkout feel faster for cashiers while keeping receipt printing available in the background.
Original PR description
- Stop awaiting the receipt print in the POS after order payment validation - Adapt tours to this behavior change task-id: 6425204 enterprise PR: https://github.com/odoo/enterprise/pull/127818 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282634 Forward-Port-Of: odoo/odoo#280002
Self-billing bills now keep numbering unique for each partner, improving traceability and reducing confusion in accounting records. Self-billing invoices can also be imported into dedicated sales journals, preventing regular sales journals from using the wrong numbering pattern.
Original PR description
This PR handles 2 cases : ===== PART 1 ===== Self-billing bill sequences should be unique per partner, as implemented in v19+. This PR backports that behavior to 17.0. ===== PART 2 ===== Previously, the `is_self_billing` option on `account.journal` was available only for purchase journals. This caused an issue when importing a self-billing invoice into a regular sales journal with quick edit mode (accounting firm) enabled. In such cases, the newly created invoices would use the self-billing sequence pattern, leading to traceability issues. This PR allows the creation of self-billing sales journals to prevent this issue. task-6103142 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282062 Forward-Port-Of: odoo/odoo#259935
Resolved issues and error corrections
This change makes an automated test for image uploads more reliable by allowing a little more time for the uploaded image to appear. It helps reduce random test failures during busy system conditions, supporting smoother releases without changing user-facing behavior.
Original PR description
Before this commit, this image field test sometimes failed because it could not find the image that had just been uploaded. Similarly to [1], we increase the waitFor timeout to 1s. Indeed, uploading an image can take time, and with high CPU usage, it could happen that the default 200ms delay wasn't enough. [1] https://github.com/odoo/odoo/pull/168196 runbot error-242406 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#281200
Refunds for payments made through Authorize.net using eCheck/ACH now use the correct bank account refund details instead of credit card details. This prevents refund failures and helps businesses process customer refunds consistently across supported payment methods.
Original PR description
**Steps to reproduce:** 1. Install Sales and payment_authorize modules 2. Enable "Online Payment" in the settings and Configure the payment method to be Authorize.net 3. Create a sale order, confirm…
**Steps to reproduce:** 1. Install Sales and payment_authorize modules 2. Enable "Online Payment" in the settings and Configure the payment method to be Authorize.net 3. Create a sale order, confirm it and create the invoice 4. Pay the invoice with an eCheck (ACH) payment method through the Authorize.net provider 5. Wait for the payment to be settled by Authorize.net (_around 24 hours_) 6. Initiate a refund of the payment **Issue:** The refund fails with error `E00003: "The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardNumber' element is invalid - The value XX is invalid according to its datatype 'String' - The actual length is less than the MinLength value` **Expected behavior:** The refund should be processed successfully regardless of whether the original payment was made by credit card or eCheck (ACH) **Why this happens:** - The `refund()` method in `AuthorizeAPI` builds the refund request using a `creditCard` payment payload - When the original transaction was an ACH/eCheck payment, the `creditCard` key is absent from the transaction details returned by Authorize.net - The resulting request is rejected by Authorize.net because it does not satisfy the minimum length constraint for `cardNumber` **Fix:** - Detects whether the original payment used `creditCard` or `bankAccount` from the transaction details and build the appropriate payload according to Authorize.net API documentation: https://developer.authorize.net/api/reference/index.html#payment-transactions-credit-a-bank-account opw-6359726 Forward-Port-Of: odoo/odoo#277742
The attendance kiosk no longer loads a presence status script that is not used in that view. This reduces unnecessary resource loading and helps keep the kiosk experience lighter without changing its functionality.
Original PR description
This commit removes the hr_attendance_presence_status.js file from the kiosk bundle, as it is not needed in the kiosk view and can cause unnecessary loading of resources. task-6468972 Forward-Port-Of: odoo/odoo#282410
Argentine delivery operations using class X document types can now be saved without entering CAI authorization details, matching government rules that require those fields only for class R delivery notes. This removes an unnecessary blocker for affected warehouse configurations while keeping validation where it is legally needed.
Original PR description
Currently, when the user attempts to create a delivery operation for a class X document type, the system prompts the user to provide values for the CAI and CAI Expiration Date fields. ## Steps to…
Currently, when the user attempts to create a delivery operation for a class X document type, the system prompts the user to provide values for the CAI and CAI Expiration Date fields. ## Steps to produce: - Install `l10n_ar_stock` with demo data - Switch Company to `(AR) Exento` - Create a warehouse - Configuration > Operation Types > Delivery Orders - Set Document Type to `'(94) MAILING X' `and try to save ## Observed Behavior: The fields 'CAI' and 'CAI Expiration Date', which represent the authorization code and expiration date issued by the government, are currently configured as required fields. **Expected Behavior:** As specified on the [government site](https://www.argentina.gob.ar/normativa/nacional/resoluci%C3%B3n-1415-2003-81316/actualizacion#:~:text=Los%20datos%20indicados%20en%20el%20inciso%20a%29%2C%20puntos%207%2C%2010%2C%2011%2C%2012%20y%2013%2C%20s%C3%B3lo%20ser%C3%A1n%20para%20los%20remitos%20clase%20%27R%27%2E): > > 12. Printing authorization code, preceded by the acronym 'CAI No. ...'. > 13. Expiration date of the receipt, preceded by the legend 'Expiration Date ...' > > 'The data indicated in section a), points 7, 10, 11, 12 and 13, will only be for 'R' class delivery notes.' These statements indicate that the information mentioned in points 12 and 13, including the **CAI** and **CAI Expiration Date** fields, is applicable only to **'R'** class delivery notes. Therefore, for class X delivery notes, these fields should be optional rather than required. ## Root Cause: According to [1], the field is configured as a required field when a Document Type ID is selected. This configuration causes the **CAI** and **CAI Expiration Date** fields to become mandatory, regardless of the document type requirements defined by the government specification. [1]- https://github.com/odoo/odoo/blob/62b05c4ea61942072b6b1fb420fe3efedb11ed14/addons/l10n_ar_stock/views/stock_picking_type_views.xml#L11-L16 ## Solution: Apply constraints that align with the government specifications, allowing the CAI and CAI Expiration Date fields to remain optional for document types where they are not required. opw-6359503 Forward-Port-Of: odoo/odoo#275533
Odoo now correctly shows employees' out-of-office return dates in Discuss, even when the viewer does not have access to the employee's company. This prevents missing availability information in sidebars, member lists, and chat banners, helping teams see colleague availability reliably.
Original PR description
*=hr_holidays,im_livechat,mail,test_discuss_full Out-of-office return dates were loaded through the partner's main user's employee_ids. That relation is company-filtered, so users without access to the employee's company did not receive leave_date_to in Discuss until opening the avatar card refreshed the data through another path. This commit fixes this behavior by loading leave_date_to from all employees linked to the partner's main user using sudo and exposing them through the all_employee_ids store relation. This makes the out-of-office indication consistently available in the sidebar, member list, and chat banner. task-6095661 Forward-Port-Of: odoo/odoo#282123 Forward-Port-Of: odoo/odoo#263149
8 changes
Enhancements to existing features
This change gives automated checks more time to wait for page updates before declaring a failure. It reduces false failures on busy machines without slowing successful test runs, helping teams get more dependable build results.
Original PR description
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests…
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests give 10 seconds. 430 call sites in addons reach these three helpers and 29 pass an explicit timeout, so 12 frames is what the other 401 get. The problem is that 12 frames is less than what the client needs on a loaded machine. Measured on "should remove file from html editor if removed from attachment list", on the wait that follows the Full composer button: - 5 to 7 frames on an idle machine; - 11 to 18 frames over 8 runs with the machine at load 10 to 20, 5 of the 8 above the 12 frames the default allows. Those 5 are failing runs, and the same test at load 13 to 29 fails 6 runs out of 6 with the 200 milliseconds, 0 out of 6 with 10 seconds. Note that a longer timeout costs nothing on a green build: the wait ends on the frame the DOM matches, so it only delays the report of a test that was going to fail anyway. Hoot fails the test itself after 5 seconds, 15 in test_js.py, which keeps bounding a wait that never resolves. This commit raises the default to 10 seconds, the delay a tour step already gets in macro.js and the one contains() and expect.waitForSteps already have. https://runbot.odoo.com/odoo/error/946094 Forward-Port-Of: odoo/odoo#282702
Resolved issues and error corrections
Vendor and employee payment addresses now include the state or province and second street line when generating ISO 20022 payment files. This helps prevent bank payment rejections, especially in regions such as the US and Canada where state/province information is required.
Original PR description
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street…
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street complement (suite, unit, ...) therefore never appear in the generated file, even when they are set on the partner, and there is no way to fix it from the record. Some North American banks reject wire transfers whose beneficiary address lacks the state/province, so those payments fail regardless of how complete the vendor record is. Return the state code and street2 alongside the other address components, from the partner for the base implementation and from the employee private address for the hr one, so the payment engine can write them in the PstlAdr block. Steps to reproduce: - Install Accounting and enable a generic ISO 20022 payment method on a bank journal - Create a vendor located in the US or Canada with a complete address, including the state and a second street line - Register a vendor payment, add it to a batch and generate the pain.001 file - The creditor PstlAdr has no state/province, and its street line only carries the first street field: the street2 part is dropped Companion enterprise PR emitting the state in the generated file: odoo/enterprise#127958 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282620 Forward-Port-Of: odoo/odoo#282518
This fixes an issue where the calendar could show the wrong weekday for users in time zones where daylight saving time starts at midnight. Calendar headers now display the correct sequence of days, avoiding confusion when planning around those dates.
Original PR description
Current behaviour: In the Calendar view (day/week/month scale), when the user's timezone observes a DST transition that starts exactly at local midnight (e.g. Africa/Cairo, since 2023), the day…
Current behaviour: In the Calendar view (day/week/month scale), when the user's timezone observes a DST transition that starts exactly at local midnight (e.g. Africa/Cairo, since 2023), the day column right after the transition gets the wrong weekday name, duplicating the previous day's name. For ex. it renders "... THU THU FRI ..." instead of "... THU FRI SAT ...", for the week surrounding April 30th 2027. To fix this we add 1 hour to the Date before reading its weekday/day from it, mirroring the workaround FullCalendar itself adopted for this same bug. It has no effect on any ordinary day (adding 1h to a correct local midnight stays within the same calendar day), and it cannot overshoot into the next day since no real-world DST gap exceeds that margin. Note: This is a known bug (https://github.com/fullcalendar/fullcalendar/issues/7633), fixed in FullCalendar v6.1.17, a major version ahead of the v4.4.0, so the fix can't be applied directly without a full library upgrade. opw-6370140 Forward-Port-Of: odoo/odoo#279836 Forward-Port-Of: odoo/odoo#279343
This change ensures that when a user clicks a mention suggestion in the message composer, the name shown on screen is the one inserted. It prevents cases where the typed search text could remain instead of the selected contact, improving reliability when mentioning people with special characters in their names.
Original PR description
Before this commit, clicking a composer suggestion could leave the composer with the typed search instead of the selected name, as in the test "Mention a partner with special character (e.g. apostrophe ')" on runbot: Failed to find 1 of ".o-mail-Composer-input" with value "..." (Timeout of 10 seconds). Found 0 instead. This happens because NavigableList looks up the clicked option by index in its current props, while the item clicked comes from the last render. Typing "@" lists the two members of the channel and typing "Pyn" drops one of them: owl assigns the filtered options one frame before it patches the list, so a click in between looks up index 1 in a list of one option, finds nothing and returns. This commit passes the rendered option to the click handler, keeping the index lookup as a fallback so that the signature stays the same on a stable version. https://runbot.odoo.com/odoo/error/946154 Forward-Port-Of: odoo/odoo#282897
Italian simplified electronic invoices now include the required virtual stamp duty information and can be exported in the simplified format when the document type requires it. The change also prevents simplified invoices from being used for non-domestic or public administration partners, reducing compliance errors.
Original PR description
- Added the BolloVirtuale in the Simplified invoice template - Now it's possible to force the Simplified format on exported invoice when the `l10n_it_document_type` is set to a simplified one - Factored the Italian partner recognition (_l10n_it_edi_is_italian) - Added a check on the invoice, no simplified format for non-domestic / PA partners Task [link](https://www.odoo.com/odoo/project.task/6226436) task-6226436 Forward-Port-Of: odoo/odoo#282839 Forward-Port-Of: odoo/odoo#274493
Clicking a table of contents entry in the HTML editor now scrolls a bit further so the target heading is clearly visible, not just barely shown at the edge of the screen. This makes navigation in longer HTML content feel more reliable and easier to follow for users.
Original PR description
When clicking on a title in the TOC, we auto-scroll to that section of the HTML, allowing users to read that part. Since [1], scrollIntoView is replaced to consider top-aligned sticky elements. As a result, instead of scrolling to make it comfortable to read the section, it stops as soon as the title is visible. Unless you are really attentive at the bottom of the screen, it can look like the scrolling did not work. This commit computes the appropriate offset to make the TOC heading more visible after scrolling. [1]: https://github.com/odoo/odoo/commit/f5cf8565e7d09edd3a29fd95537381fb70d75785 Task-6394193 Forward-Port-Of: odoo/odoo#278304
This fixes an issue in the HTML editor where formatting from an outer table could incorrectly overwrite the colors of a table placed inside it. Business documents and web content with nested tables will now keep their intended visual styling after editing or normalization.
Original PR description
Problem: When a `table` with a `color`/`backgroundColor` contains a nested `table`, `distributeTableColorsToAllCells` propagates the outer table's color to every `td` in the subtree, including cells…
Problem:
When a `table` with a `color`/`backgroundColor` contains a nested `table`, `distributeTableColorsToAllCells` propagates the outer table's color to every `td` in the subtree, including cells belonging to the inner table. The inner table's own color is then discarded since its `td`s already have a value.
Cause:
`table.querySelectorAll("td")` returns every `td` in the entire subtree, not just the table's own direct cells.
Solution:
Scope the selected `td`s to `td.closest("table") === table`, so a table's color is only distributed to its own cells.
Steps to reproduce:
1. Add a `background-color` to an outer `table`.
2. Nest a `table` with a different `background-color` inside one of its cells.
3. Load/normalize the content in the editor.
4. Observe both tables' cells carry the outer table's color.
opw-6438972
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#281850
Forward-Port-Of: odoo/odoo#281413DIN 5008 business documents now show dates in the expected German-style format for Germany, Austria, and Switzerland, regardless of the user's language settings. Company registry information is also shown only when relevant and uses country-appropriate wording, reducing confusion on official documents.
Original PR description
* = de, din5008, din5008_purchase, din5008_repair, din5008_sale **Steps to reproduce:** * Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`) * Set the document…
* = de, din5008, din5008_purchase, din5008_repair, din5008_sale
**Steps to reproduce:**
* Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`)
* Set the document layout to **DIN 5008** and generate any PDF report (invoice, quotation, purchase order, etc.).
**Observed behavior (date format):**
* All dates in the information block (Invoice Date, Due Date, Delivery Date, Order Date, etc.) are rendered in `yyyy-mm-dd` format instead of the expected `dd.MM.yyyy` format used in DE, AT, and CH.
**Observed behavior (commercial register):**
* The footer always shows `HRB-Nr.:` regardless of whether the company has a commercial register entry.
* The abbreviation `HRB-Nr.:` appears even for Austrian and Swiss companies, where the commercial register number is a German-specific concept.
* In the company form view, the field is labeled generically as "Company ID" instead of "Commercial Register Number" for German companies.
**Cause (date format):**
* All `t-options="{'widget': 'date'}"` directives across the DIN 5008 template family rely on the active user's language locale for date formatting. If the user language is not `de_DE`, dates render in the locale's default format (e.g. `yyyy-mm-dd` for `en_US`).
**Cause (commercial register):**
* The footer renders `company.company_registry` unconditionally with no country guard and no label.
**Fix (date format):**
* Add `'format': 'dd.MM.yyyy'` explicitly to all `t-options` date widgets across all DIN 5008 report templates (`l10n_din5008`, `l10n_din5008_sale`, `l10n_din5008_purchase`, `l10n_din5008_sale_subscription`, `l10n_din5008_repair`, `l10n_din5008_account_followup`, `l10n_din5008_industry_fsm`).
* This is correct for all three countries using DIN 5008 (DE, AT, CH), which all follow the `dd.MM.yyyy` convention.
**Fix (commercial register):**
* Remove the hardcoded `HRB-Nr.:` label from the footer and instead render `company.partner_id.company_registry_label` (which is country-aware).
* Update the duplicate contact warning message to use the country-aware label via `company.partner_id.company_registry_label`, backed by a new `_get_company_registry_labels` override in l10n_de that registers `Commercial Register Number` for `DE`.
* In the company form view (`l10n_de`), hide the generic "Company ID" field for German companies and show a relabeled instance with `string="Commercial Register Number"` instead.
opw-6392649
Forward-Port-Of: odoo/odoo#282964
Forward-Port-Of: odoo/odoo#2790855 changes
Enhancements to existing features
This change increases the default wait time used by web interface tests so they are less likely to fail on busy or slower machines. It aligns these waits with existing test behavior and improves confidence in automated test results without affecting normal successful runs.
Original PR description
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests…
Before this commit, waitFor, waitForNone and waitUntil gave the DOM 200 milliseconds, which the loop turns into 12 animation frames, while contains() and expect.waitForSteps sitting in the same tests give 10 seconds. 430 call sites in addons reach these three helpers and 29 pass an explicit timeout, so 12 frames is what the other 401 get. The problem is that 12 frames is less than what the client needs on a loaded machine. Measured on "should remove file from html editor if removed from attachment list", on the wait that follows the Full composer button: - 5 to 7 frames on an idle machine; - 11 to 18 frames over 8 runs with the machine at load 10 to 20, 5 of the 8 above the 12 frames the default allows. Those 5 are failing runs, and the same test at load 13 to 29 fails 6 runs out of 6 with the 200 milliseconds, 0 out of 6 with 10 seconds. Note that a longer timeout costs nothing on a green build: the wait ends on the frame the DOM matches, so it only delays the report of a test that was going to fail anyway. Hoot fails the test itself after 5 seconds, 15 in test_js.py, which keeps bounding a wait that never resolves. This commit raises the default to 10 seconds, the delay a tour step already gets in macro.js and the one contains() and expect.waitForSteps already have. https://runbot.odoo.com/odoo/error/946094 Forward-Port-Of: odoo/odoo#282702
Resolved issues and error corrections
Non-admin users can once again send Vietnamese electronic invoices through SInvoice after migrating from version 18. The fix restores the expected invoicing workflow while keeping administrative credential fields protected.
Original PR description
### Steps to Reproduce: 1). Install l10n_vn_edi_viettel ('Vietnam E-Invoicing') module in v18. 2). Migrate the database in any version above v18. 3). AccessError will appear while generating ('Send…
### Steps to Reproduce:
1). Install l10n_vn_edi_viettel ('Vietnam E-Invoicing') module in v18.
2). Migrate the database in any version above v18.
3). AccessError will appear while generating ('Send to SInvoice') on invoice for non-admin users.
### Issue:
- In v18, users were able to send and generate documents via (Send to SInvoice). Since v18.1 onwards, field access [check] is enforced during this flow, and since `l10n_vn_edi_username` is restricted to admin users only [here], non-admin users hit an AccessError as soon as
`_l10n_vn_edi_get_credentials_company` reads this field on`res.company`.
```py
You do not have enough rights to access the field "l10n_vn_edi_username" on Companies (res.company). Please contact your system administrator.
Operation: read
User: 12
Groups: allowed for groups 'Role / Administrator'
```
### Solution:
- This commit fixes the issue by adding a `sudo()` call on the company inside [_l10n_vn_edi_get_credentials_company] itself, so that non-admin users can successfully send and generate documents like in the previous version, without any hassle.
[check]: https://github.com/odoo/odoo/blob/5ca10578a2fd1b40cd371ed5ad20c1654dfe54d3/odoo/orm/models.py#L3384
[here]: https://github.com/odoo/odoo/blob/5ca10578a2fd1b40cd371ed5ad20c1654dfe54d3/addons/l10n_vn_edi_viettel/models/res_company.py#L9
[_l10n_vn_edi_get_credentials_company]: https://github.com/odoo/odoo/blob/ecc267a231958c2dd99a7287c6bd1adbdbd22965/addons/l10n_vn_edi_viettel/models/account_move.py#L885
Ticket [link](https://www.odoo.com/odoo/project.task/6434854)
opw-6434854This fix ensures that when a down payment taken through Point of Sale is refunded, it is no longer counted again when the related sales order is settled or invoiced. This prevents customers from being charged twice and keeps the invoicing totals accurate.
Original PR description
The following commit resets qty_invoiced to zero on sale order lines paid by a POS order when that order is refunded. https://github.com/odoo/odoo/commit/ac39aa4f68dfc77011c39e468e3f60e0338a3c69 However, it does not handle the sale order line created for a refunded POS down payment. That line keeps `qty_invoiced` = -1, which causes the refunded amount to be included again when settling or invoicing the sale order. Steps to reproduce: - Create a sale order. - Pay a down payment through the POS. - Refund the down payment order from the POS. - Settle the remaining amount from the POS or invoice the sale order from the backend. Result: - The generated invoice includes the sale order total plus the refunded down payment. - Sale order `amount_invoiced` will be the down payment amount. Fix: - Delete the refunded downpayment to match the sale flow. - Include refunded down payments in the amount_invoiced computation. opw-6378891 Forward-Port-Of: odoo/odoo#278011
This change makes the peer-to-peer connection test wait until the full set of connections is established before measuring the result. It prevents random test failures on busy or slower machines, improving confidence in the chat system’s reliability.
Original PR description
Before this commit, "mesh peer to peer connections" fails at random on a loaded machine, counting fewer connections than its ten users make:
[toBe] expected values to be strictly equal
> Expected: 90
> Received: 81
This happens because the test counts the peers as soon as its addPeer calls resolve. addPeer awaits the readiness promise of the peer, which also resolves, with false, when that peer is disconnected. A connection slow to open reaches the recovery watchdog, which tells the other side to drop the peer, drops it locally and adds it back without awaiting it. The awaited promises can therefore all be settled while recovered peers are still connecting.
This commit waits for the mesh to reach its full size before counting, so that a recovery in flight no longer decides the result. With the browser CPU throttled, the test fails about half of its runs before this commit, and none after.
Forward-Port-Of: odoo/odoo#282719This update removes an old, unused view attribute from the Philippine 2307 wizard form. It does not change how the form works, but it keeps the configuration cleaner and avoids compatibility issues with newer Odoo versions.
Original PR description
The `modifiers` attribute was used in older Odoo versions to define field properties (invisible, readonly, required, etc.) Since the field already declares these same properties directly…
The `modifiers` attribute was used in older Odoo versions to define field properties (invisible, readonly, required, etc.) Since the field already declares these same properties directly [state](https://github.com/odoo/odoo/blob/14.0/addons/account/models/account_move.py#L150-L155) , [amount_tax_signed](https://github.com/odoo/odoo/blob/14.0/addons/account/models/account_move.py#L229)
(e.g. `invisible=...`, `readonly=...`), the `modifiers` attribute is redundant and serves no purpose.
This attribute was never added manually by us — it was auto-generated by Odoo Studio when the default view was created. Studio's default views inject `modifiers` alongside the direct attributes. [Here](https://github.com/odoo/odoo/pull/104741/changes/975e875046691c898e8c1acb87d3626cd299e5aa#diff-dfebe5a93e1b8880e88268b024be4c6f106d144b20298d7bb6c4ae09a18bafd0L67-L145)
Also the `modifiers` attribute was fully simplified [removed](https://github.com/odoo/odoo/pull/104741/changes/975e875046691c898e8c1acb87d3626cd299e5aa#diff-849f1ed2a35a8b0b9cdd67f8e34de5d2ea7bf928103a83828587ba7ec14a62e4L52) starting from version 17.0, where views rely exclusively on direct attribute expressions (`invisible`, `readonly`, `required`) instead of the `modifiers` JSON encoding [main Patch](https://github.com/odoo/odoo/pull/104741) Keeping it around in the arch is therefore dead code with no effect.
However it needs to give the error on 17.0+ like this
```
ERROR LOG:
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_NOELEM: Expecting an element data, got nothing
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_INVALIDATTR: Invalid attribute modifiers for element field
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_EXTRACONTENT: Element tree has extra content: field
```
As the modifer has been remove from the field [common.rng](https://github.com/odoo/odoo/pull/104741/changes/975e875046691c898e8c1acb87d3626cd299e5aa#diff-849f1ed2a35a8b0b9cdd67f8e34de5d2ea7bf928103a83828587ba7ec14a62e4L52) RelaxNG schema but modifiers set on fields here root tag is **form**, and the modifiers sit on fields inside a nested list. And Form views aren't RNG-validated from 17.0 till now —
[@validate('calendar', 'graph', 'pivot', 'search', 'list', 'activity')](https://github.com/odoo/odoo/blob/f0e58b9324af18d0cf0264aec2886d098e997f03/odoo/tools/view_validation.py#L314) has no form, and there's no [form_view.rng](https://github.com/odoo/odoo/tree/19.0/odoo/addons/base/rng).
Current senario
<img width="998" height="415" alt="image" src="https://github.com/user-attachments/assets/1a678c8f-8401-4e12-826f-9e98f6f2fe20" />
After removing the modifer: it show the same view because of field property
<img width="998" height="415" alt="image" src="https://github.com/user-attachments/assets/1a678c8f-8401-4e12-826f-9e98f6f2fe20" />
After removing the modifer still it shows the **modifiers="{'readonly':true, 'required':true}"** because the modifer is stay in the 14.0 but the 17.0 onwards it was not please see the scrrenshot its field preprty always.
<img width="1003" height="462" alt="image" src="https://github.com/user-attachments/assets/5e833924-b17c-417f-9e63-5a01c185f588" />
This Fix removes the unused `modifiers` attribute from the view arch, keeping only the direct attribute already present, with no functional change to the view's behavior.
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#281271
Forward-Port-Of: odoo/odoo#27997648 changes
New functionality added to Odoo
This change adds support for showing accurate Click & Collect availability for rental products by taking the selected rental dates into account. Customers get clearer stock and checkout behavior, including better date selection and out-of-stock handling, reducing failed purchases and confusion.
Original PR description
**Purpose:**
Click & Collect and Rental are not working together, the rental dates are not used to display the availability of the product.
**Specification:**
Create a new bridge module between website_sale_collect and website_sale_renting to ensure that we use the rental dates to compute the availability if this is a rental product.
Task-6081690
See also:
- https://github.com/odoo/odoo/pull/259321Adds support for Ivory Coast's FNE electronic invoicing requirements so companies can prepare and send compliant invoice data from Odoo. This helps businesses operating in Côte d'Ivoire meet local tax reporting obligations more efficiently and reduces manual compliance work.
Original PR description
task-6110046
Enhancements to existing features
Employees with referral-only access can now view their own referral links in a read-only format, helping them understand how their shared links are performing. The Points menu is also available to these users, making referral progress easier to follow without granting extra editing permissions.
Original PR description
Before: - User having group: `User: Referral only` was only able to create a referral link but not able to track how there referral link is performing. After: - User will have read-only view for their referral links. - Points sub-menu will be visible to `User: Referral Only`. task: 6402714
The Belgian payroll configuration now includes the required reporting details for recoverable 0% overtime. This helps ensure overtime is classified correctly for social security, withholding tax, and official Belgian payroll declarations.
Original PR description
- Extended the OVERTIME26 work entry type with essential Belgian reporting metadata: category_ids (Remuneration, ONSS, Withholding tax bases), dmfa_code=1, and l10n_be_egov3_code=1102001. Task: 6358853
Customers booking appointments with related accessory products are now sent to the cart first, making it easier to add complementary items before checkout. If an appointment slot becomes unavailable while in the cart, it is removed automatically and the customer is clearly notified, helping avoid payment errors while preserving other valid bookings.
Original PR description
This PR improves the website appointment flow by adapting the checkout redirection when accessory products are present and ensuring proper cart validation for unavailable bookings. When an appointment type includes accessory products, users are now redirected to the cart page to look for complementary items before proceeding, with the button label updating dynamically. Additionally, any booking slots that become unavailable while in the cart are automatically removed during checkout validation, preserving other valid bookings and displaying a clear notification to the user. task-5975874
WhatsApp business accounts can now block repeat spam senders per account, helping teams reduce unwanted incoming messages. Staff can add numbers to a blocklist and manually block or unblock them from the form view, with Odoo syncing the action to WhatsApp automatically.
Original PR description
Purpose: Prevent incoming spam by blocking WhatsApp numbers that repeatedly send unwanted messages to the WhatsApp business account. Specifications: - Allow blocklisting WhatsApp numbers per WhatsApp account. - Creating a blocklist entry automatically triggers an API call to block the number on WhatsApp. - Allow manually blocking or unblocking numbers from the form view. Documentation: https://developers.facebook.com/documentation/business-messaging/whatsapp/block-users Task-5236975
Obsolete internal duplication logic was removed from Sales Subscription and Sales Renting to match the updated core product behavior. This reduces maintenance overhead and helps keep sales-related product handling consistent across Odoo.
Original PR description
Remove obsolete _duplicate_pricelist_rules_on_copy overrides from enterprise modules (sale_subscription, sale_renting) following its removal from the product module. This avoids dead code and ensures consistency with the updated core duplication behavior. task-5470688
The accounting reconciliation interface was updated to work with the newer OWL framework used by Odoo. This helps keep bank reconciliation and related accountant workflows maintainable and compatible without introducing major functional changes for users.
Original PR description
This pr will do some changes to be compliant with owl3. What has been done: - Change of some props to the new system - Remove use of useSubEnv - Remove use of onWillRender Also apply the EsLint on all files. task-6353237
Turkish companies can now generate reconciliation letters in Odoo using a format aligned with local legal expectations. The update adds bilingual letter content, address sections, closing text, and signature areas to reduce manual work and support audit readiness.
Original PR description
SPEC: - TR companies are legally required to exchange reconciliation letters (Mutabakat Mektubu) per TTK Article 94 to confirm outstanding balances with partners. - No standardized reconciliation letter exists in Odoo for Turkish localization, forcing manual off-system processes with reduced traceability. IMP: - Adjust customer statement report to comply with TR reconciliation letter format: title, address blocks, intro/closing messages (EN + TR), and signature blocks. - Provide Turkish translations for all letter content per legal requirement. Impact: - Turkish companies can generate and send legally compliant reconciliation letters directly from Odoo, eliminating manual workarounds and improving audit readiness. taskID-6121545
Cash-basis tax entries created from bank reconciliation can now be removed when payments are unreconciled, as long as accounting locks allow it. If removal is not allowed, the system keeps the safer reversal behavior and adds checks to warn users about sequence gaps that could affect tax return audits.
Original PR description
Problem --------- Currently, once a CABA move is created through the bank reco widget, it is impossible to draft/unlink it, the move can only be reverted. This leads to noisy journal when users unreco - reco their CABA payment. Do this a few times and it gets impossible to audit. Objective --------- The objectives of this change are as followed: 1. Allow for CABA moves to be unlinked once the payment is unreconciled. This is only allowed when the move is not locked behind HARD locks and tax lock. 2. In the case the CABA move is locked behind mentioned locks, revert it as it currently work. 3. Since the deletion/creation of moves can create holes in the CABA journal sequence (which is not really allowed in audits), it adds a Tax Return default check to warns the user in case of a hole sequence in the moves included in the Tax Return/End of the Year Statement. task-6226555
This update makes a small internal change in Web Studio’s report template handling to support future improvements. It does not introduce visible changes for users today, but helps keep reporting customization capabilities ready for upcoming enhancements.
Original PR description
Pass compile_context in parameters of `_compile_expr` to prepare future improvements in QWEB according to expressions. Task-6466187
Project budget information is now more accessible from project tasks and dashboards through a new Budgets tab. The project settings page is also cleaner because the Budget shortcut is hidden when no budgets exist.
Original PR description
- Add Budgets top-bar tab to project tasks and dashboards. - Hide the Budget stat button on the project settings page if zero budgets exist. task-5969230
Austrian small entrepreneurs can now use their domestic tax number when a VAT number is not available, allowing required Fiskaly registration and POS workflows to proceed. The update also improves an internal library patching mechanism to avoid issues when patched libraries need to read bundled data files.
Original PR description
Austrian Kleinunternehmer (small entrepreneurs) aren't issued a VAT number, only a domestic Steuernummer, but Fiskaly registration requires "vat" to be set. Add `l10n_at_stnr` on `res.company` and fall back to it wherever `l10n_at_pos` required "vat" like Fiskaly registration or else. Also fix patching a library's loader after import replaced it with a stand-in missing `get_resource_reader()`, breaking `importlib.resources` for any patched lib reading bundled data files. `exec_module` is now overridden on the loader instance instead. --- Task: https://www.odoo.com/odoo/project/1737/tasks/5993536
Spreadsheet list side panels now use the same drag-and-drop behavior and visual feedback as other spreadsheet areas. This makes reordering dimensions and sorting rules feel more consistent and easier to understand for users.
Original PR description
Current behavior before PR: - Dragging list dimensions and sorting rules felt visually different from pivot dimensions and global filters in the side panel. - The list side panel used a separate drag-and-drop utility that did not match the consistent UX of other spreadsheet components. Desired behavior after PR is merged: - List dimensions and sorting rules now share the same drag-and-drop behavior and visual feedback as pivot dimensions and global filters. - All reorderable items in the side panel now look and feel the same, providing a consistent user experience across the spreadsheet. - Use the `Section` component wherever applicable to keep the UI consistent. Task: [6219600](https://www.odoo.com/odoo/project/2328/tasks/6219600)
Employee document folders are now created directly in bulk instead of being recreated unnecessarily or processed one by one. This improves setup and payroll document organization performance, especially for companies with many employees.
Original PR description
* Employee folders could be unnecessarily recreated * Payroll folders were created one by one Temporary PR related to #127973 Task-6344800
Spreadsheet-related automated tests were updated to align with the move to Material Symbols icons in the spreadsheet library. This helps keep quality checks reliable after the visual icon system change, with no expected direct impact on daily users.
Original PR description
this commit adapts the tests to the switch to Material Symbols icons in the external library o-spreadsheet. Task: 6276321
Users can now use a middle click on the expand button in signing-related form dialogs to open the form in a new browser tab. This makes it easier to keep the current workflow in place while reviewing or editing a related form separately.
Original PR description
This commit adds the ability to detect a middle click on the Expand button to the Dialog API. This is achieved through the `t-custom-click` directive. The expand callback function that is given to the Dialog API, will now receive two parameters: the event and whether it's a middle click. Note that, the custom directives and the global values used for the `t-custom-click` are mandatory for each Owl app. This commit also uses the new API to allow the FormViewDialog and x2ManyFieldDialog form dialogs to expand to a new tab. task-id: 5429014
Online bank synchronization can now automatically reconnect when a connection breaks. This reduces manual follow-up for users and helps keep financial data imports running more reliably.
The signing activity is renamed from "Request Signature" to "Signature Request" so users see wording that matches the rest of the app. The activity icon is also muted to better align visually with other activity icons, creating a more consistent experience.
Original PR description
Renaming activity from "Request Signature" to "Signature Request" to better align with the wording used in other places. Change the template icon to muted to better match the other activities icons. Task-6317051
The Point of Sale navigation menu now displays icons and labels with consistent alignment and spacing. This makes the burger menu and LNA button easier to read and improves the overall visual clarity for users.
Original PR description
In this commit - ------------------------------- icon and label in the burger menu and LNA button are now properly aligned with consistent spacing for better visibility. Task-6391440 Related PR-https://github.com/odoo/odoo/pull/280203
Kitchen staff can now see the course sequence for self-order and kiosk orders in the preparation display. This makes those orders consistent with restaurant point-of-sale orders and helps kitchens prepare items in the intended order.
Original PR description
Following this commit: ==== - Course sequence would also be visible in kitchen display for self-order/kiosk same as pos_restaurant. task-6255005 Related PR : https://github.com/odoo/odoo/pull/269216
Time off that falls in a period already covered by a payslip is now handled automatically instead of requiring manual deferral by HR. This reduces payroll corrections, avoids complex conflicts between overlapping absences, and adds extra approval safeguards for past leave that can affect validated payroll.
Original PR description
Currently when a time off is created for a period already covered by a payslips, a time off officer needs to differ it manually but if there is a conflict with another time off it's too complex to be deferred. In that case the initial payslips should be reverted and then a new one should be created.
The Frontdesk Partnership homepage has been redesigned to better match the existing Frontdesk card-based experience. Visitors can now enter barcodes directly from the card or start camera scanning immediately, making check-in smoother and more intuitive.
Original PR description
In this PR, we have improved the homepage design to provide a more consistent and intuitive user experience: * Kept the card-based design consistent with the Frontdesk app and added an option to manually enter the barcode directly within the card. * When tapping the barcode option, the camera now opens directly for barcode scanning, removing the need for manual barcode entry from the scanning flow. Task-6364852
The signing process now handles PDF updates more carefully, allowing multiple signatures on the same document while keeping the original file structure intact. This improves reliability and supports more complex signing workflows without unnecessarily changing untouched pages.
Original PR description
Refactor PDF signing to use the incremental merge workflow, allowing multiple signatures per document while preserving the original PDF structure. Overlays are now merged incrementally, and only edited pages are updated. This improves consistency in the signing pipeline and supports more complex signing scenarios. task-5426461
The accounting dashboard now avoids repeated bank institution lookups when several unconfigured bank journals are shown. This makes the dashboard become usable faster and reduces stalls when the bank synchronization service is slow.
Original PR description
An accounting dashboard with a dozen unconfigured bank journals took seconds to become usable, and stalled entirely whenever the synchronization proxy was slow to answer. The server resolves the journal to its company and keys the proxy request on that company's fiscal country, and the widget is only rendered for journals of the active company, so the journal argument selected a company that was already known. The hook now sends one request per active company and hands the resulting promise to every widget that asks for it, dropping the journal argument along the way. The fetch also moved from the widget's start to its mount. The shared promise resolves immediately for every widget but the first, and the grid sizes itself from the width of a container that is only laid out once the card is in the DOM.
Payroll run reporting for UAE companies now uses metrics tailored to local payroll needs rather than a generic view. Salary rule and category updates also help payroll teams review UAE pay runs with information that better matches their business requirements.
Original PR description
The payrun metric for AE companies has been modified in order to adapt the payrun to the localization requirement instead of a generic view to cater for the business and payroll officers needs. Moreover few changes have been introduced to salary rules and categories. Task: 6326637
The Ecuador ATS reporting tests were updated to match a platform-level change in how certain grouped results are ordered. This keeps automated checks aligned with the intended behavior and helps prevent false test failures without changing business functionality.
Original PR description
Following changes to the ORM methods _read_group_orderby and _order_field_to_sql, query results are now ordered according to the sequential definition of selection fields (if ordered by a selection field ofc). Adapt the tests to take this new ordering into account. Related: odoo/odoo#280940 Task: 6425647
Payroll teams can now set dashboard warnings relative to today, making urgent warnings appear at the top as time moves forward. Email alerts skip these rolling Today-based warnings to avoid sending the same notification every day.
Original PR description
Dashboard warnings are grouped and sorted by their warning date, and every existing Closing On option anchors to a payrun, a contract, or a calendar boundary. Today is added as the first choice so a warning can sit at the top of the dashboard. The offset applies as usual, so the row reads "N days After Today". The reference moves with the clock, so the distance is constant. _cron_payroll_warning_email_alert skips Today warnings: its (today - warning_date).days == email_alert_days check is constant for them and would otherwise re-send the alert daily. task-6456127
Desktop users can now add call flow nodes by simply clicking an item in the palette, matching the easier mobile behavior. Drag and drop remains available, but it now starts only after the pointer moves far enough, reducing accidental drags and making flow editing smoother.
Original PR description
In the call flow editor, nodes can currently be added by dragging them from the desktop palette onto the canvas. On mobile, selecting a node from the dropdown adds it directly to the center of the canvas. Allow desktop users to get the same behavior by clicking a palette item. Keep drag and drop available by starting it only after the pointer has moved beyond a small threshold. task-6472451
The Colombian electronic invoicing app now has updated demo data and a clearer contact view for DIAN-related information. Demo mode is enabled by default for the demo company, making it easier for users to test and demonstrate the workflow safely.
Original PR description
Updating some demo data and adjusting DIAN partner view. DIAN demo mode is now default for the demo company. task-6454347
The attendance Gantt view now shows the same information bar already available in the calendar view. Managers can quickly see total worked hours, extra hours, and remaining hours in one place when reviewing attendance schedules.
Original PR description
The information bar which was being displayed in the Calendar view will now also be shown in the Gantt view with: - Total Worked Hours - Extra Hours - Left Hours (from hr_holidays_attendance) **task-6259363**
The Belgian payroll employee type previously labeled "PFI/Activa" has been renamed to "PFI/IBO". This makes the label more accurate for regional training contracts in Wallonia and Flanders and avoids confusion with the unrelated Activa scheme.
Original PR description
The employee type "PFI/Activa" is incorrect because Activa is not related to Dimona Category IVT. Renamed "PFI/Activa" to "PFI/IBO" to properly reflect the Belgian regional training contracts (PFI in Wallonia, IBO in Flanders). Task: 6478957
Resolved issues and error corrections
The vehicle model engine section now keeps related power fields together, so the form no longer visually shifts when users change the selected power unit. An unused horsepower tax field was also removed, reducing clutter in fleet-related views.
Original PR description
The order of fields in "engine" section of car model is changed when selecting an other Power Unit. Cause: "power" and "horsepower" fields are conditionnaly invisible depending on the selected unit but at different positions. Solution: moving them next to each other. Removing "horsepower_tax" field as not used for any computation Task: 6428275
The accounting app now better detects fiscal years that overlap existing ones, including cases where a new, longer fiscal year fully contains an existing shorter period. This helps prevent inconsistent accounting period setup and reduces the risk of reporting or closing-period errors.
Original PR description
Before this commit: - The current constraint for overlap check that we have allows if we define a new, larger fiscal year that completely swallows an existing smaller one (e.g., creating Aug 2025 - Nov 2026 when Sept 2025 - Oct 2026 already exists). After this commit: - The constrain domain was changed to consider the above missed case.
The Sign template editor no longer performs an unnecessary background lookup when opening or preparing templates. This removes wasted processing without changing the visible editing experience, helping keep the editor leaner and more reliable.
Original PR description
The editor fetched a sign.item.role record to set currentRole, which has no effect and no use, so every value computed from it is overwritten right after. task-6449467
The Planning schedule side panel now shows the Open Shifts and Resources filters again. This lets dispatchers quickly find unassigned work and filter schedules by technician, restoring an important day-to-day scheduling control.
Original PR description
Steps to reproduce: 1. Install the planning_field_service module. 2. Navigate to the Planning app -> Schedule (Main Calendar View). 3. Check the right-hand calendar side panel. Issue: The Open Shifts and Resources checkboxes/filters are completely missing from the side panel, preventing dispatchers from filtering the schedule by specific technicians or viewing unassigned shifts. Cause: the resource_ids field was completely removed from the planning_view_calendar XML. Because the field was no longer present in the view architecture, the OWL calendar renderer stopped generating the dynamic resource filter in the side panel. task-6452329
The Phone app now shows the full Telnyx location when users search for phone numbers to buy, making it easier to identify where numbers are based. It also removes a misleading settings menu that opened a page without any Phone-specific settings.
Original PR description
When searching for a number to buy, the Location column showed only a
fragment of where the number comes from —> usually the bare state ("ON")
while Telnyx's own search shows the whole thing ("GRIMSBY, ON, CA").
This commit fixes that and shows the location like its shown on Telnyx +
a small ux change which is removing the configuration/settings menu
because Phone app doesn't have settings actually.
Task-6456328Users can now create a new warehouse directly while setting up stock-by-vehicle mappings. This removes an unnecessary setup blocker and makes configuring vehicle-based warehouse assignments faster.
Original PR description
Before this commit, users could not create a new warehouse directly from the 'stock by vehicle' mapping view because the `warehouse_id` field had the `no_create` option enabled.
With this commit, we remove `options="{'no_create': True}"` from the `warehouse_id` field in both the list and form views. This enables on-the-fly warehouse creation directly from the vehicle mapping settings.
task-6381795
Forward-Port-Of: odoo/enterprise#124240Payroll warning messages now open safely on employee records, even when no related version data is found. Warnings configured for both the payroll dashboard and employee records can now appear in both places, helping users see the right alerts where they need them.
Original PR description
Two issues could occur when using payroll warnings on employee/version records: * Opening an employee form could raise an `AttributeError` for model warnings when the warning evaluation returned an empty `base` recordset. The code attempted to access `version_ids` before checking this case. * A warning configured to be displayed both on the dashboard and on the model was excluded from one of the views. Check the warning result before accessing employee versions, and filter dashboard warnings based on `display_on_dashboard` instead of `display_on_model`. This allows model warnings to be evaluated safely and makes it possible to display the same warning both on the dashboard and on the corresponding model. task-6472369
The Discuss app badge now shows the correct red counter in Enterprise setups. A test-only dependency was moved out of the main mail enterprise module so it can install automatically as intended, restoring the expected user interface behavior.
Original PR description
Before this commit, the discuss badge counters were green because `mail_enterprise` module could not be auto-installed with `mail` and `web_enterprise` installed. This comes from recent addition of `test_tools` from a test in `test_update_notification` requiring this module. We want `mail_enterprise` to auto-install with only `mail` and `web_enterprise` modules, so the `test_tools` should only affect a test module. This commit fixes the issue by moving the test in `test_mail_enterprise`, so that `mail_enterprise` can auto-install itself as expected. Task-6475496 Before <img width="397" height="421" alt="Screenshot 2026-08-18 at 12 20 09" src="https://github.com/user-attachments/assets/9bd7e001-ecc8-44bb-8d77-342835a08dd0" /> After <img width="398" height="422" alt="Screenshot 2026-08-18 at 12 21 50" src="https://github.com/user-attachments/assets/b21611ca-9055-4922-ad58-9813f3fb6964" />
The bank journal screen now hides the “send now” reminder and connection request when the journal is no longer using online synchronization as its bank statement source. This prevents users from seeing misleading prompts that do not apply to the selected bank setup.
Original PR description
In this commit:https://github.com/odoo/enterprise/commit/86659741990de2ba9c8bf738207edf0e8a0ba8c4 the invisible condition on action send reminder was wrongly removed Now, the "send now" button and the connection request was shown as soon as we have an account online account link to the journal. But when changing the bank statement source, the information would still be there. Changing the invisible condition to hide it when the bank statement source is different from only_sync no task id
Code cleanup and technical improvements
The inventory barcode app was updated as part of a broader platform migration to keep it compatible with the next version of Odoo's interface framework. This is an internal cleanup with no expected change to day-to-day warehouse scanning or stock counting workflows.
Original PR description
As part of the Owl 3 migration, replace onWillUpdateProps hook with the appropriate Owl 3 alternatives.
This update simplifies how commission plan charts are displayed by using a shared chart handling mechanism already adopted elsewhere. It reduces duplicated code and prepares the feature for newer platform changes, with no expected change to day-to-day user workflows.
Original PR description
The commission plan graph duplicated the same Chart.js lifecycle as the community components: an `onWillStart` loading the `web.chartjs_lib` bundle, then render on mount, destroy and re-render on every patch, destroy on unmount. Here we drop it for the hook extracted in the community PR. `useChart(getConfig)` is called from the constructor as a field and owns the canvas signal ref, so the template takes its `t-ref` from `this.chart.ref`. `spreadsheet_edition` patches `GraphRenderer` and reads its chart instance, which now lives behind the hook's accessor. WHY: useLayoutEffect is deprecated in OWL3 NOTE: the `JSON.parse` of the record value that `setup` did is dropped - `renderChart` re-parsed it on every run anyway, and nothing reads `this.data` before the chart is built. Community PR: odoo/odoo#282745
The map view code was updated to use the newer application lifecycle approach required by the next Odoo web framework version. This is an internal technical cleanup with no expected change to user-facing map behavior.
Original PR description
Replace `useLayoutEffect` with `onMounted` (functionnaly 1:1 equivalent because of the empty dependency array). Seperating in its own commit for simplicity of security review. WHY: useLayoutEffect is deprecated in OWL3
This update refreshes internal code used by spreadsheet editing screens and VoIP call controls to align with newer platform standards. It should help maintain compatibility and reduce maintenance risk without changing the expected user experience.
This update simplifies internal invoice creation code across sales-related modules, including subscriptions, loyalty, tests, and Brazilian stock EDI. It should make future maintenance safer and more consistent without changing day-to-day user workflows.
The audio visualizer was updated to use the newer supported approach in Odoo’s interface framework, replacing an outdated internal mechanism. This reduces future upgrade risk and adds test coverage to help ensure the visualizer continues working correctly.
Original PR description
Replaced `useLayoutEffect` with `computed` because `useLayoutEffect` is deprecated in OWL3. `barHeights` is pure derived state from `props.frequencies` and `barCount` (a signal). `computed` auto-tracks both dependencies and re-evaluates without side effects, making it a natural fit for this case. When commenting out the useLayoutEffect there was no error, the code we refactored had NO TEST coverage. A test was written to ensure our fix was correct, and it was tested against the previous useLayoutEffect: - Passed with previous useLayoutEffect. - Failed with previous useLayoutEffect commented. - Passed with our OWL3 replacement.
This change renames an internal user access group to make its purpose clearer and more consistent across the system. It should not change day-to-day workflows, but helps maintain the platform and reduces confusion for future updates.
5 changes
Enhancements to existing features
Adds a dedicated view for French e-reporting accounting entries so users can see relevant reporting details more easily. This avoids changing the standard accounting entry view while improving visibility for France-specific compliance workflows.
Original PR description
This commit will add a new view for the ereporting moves to be able to see some specific info without touching the base move view. task-6274213 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This fix prevents an error when users change a product to a service after removing its unit of measure. It improves reliability in Inventory product setup by safely handling products without a unit configured.
Original PR description
Steps to replicate: 1. Install `stock`. 2. In Inventory > Configurations > Settings, enable the setting "Units of Measure". 3. Create a new product. 4. Remove the Unit. 5. Enable "Track by Inventory". 6. Swap Product Type to Service. A traceback error results. https://drive.google.com/file/d/1S_5Xdlhfe03hGaykewdIACmaaraCQcOw/view?usp=sharing A product's unit of measure's precision is passed to `float_is_zero` without first confirming that the unit of measure exists. opw-6172389 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
French customers with a valid SIREN or SIRET number are now correctly treated as business customers even when no VAT number is recorded. This keeps the French e-Invoicing option available for eligible invoices and avoids unnecessary manual workarounds.
Original PR description
**Steps to reproduce:** - Install module `l10n_fr_pdp` and configure French e-Invoicing. - Create a customer has a valid SIREN/SIRET (company_registry) but no VAT number. - Create an invoice for the customer and confirm the invoice. - Check the available sending methods. **Observed Behavior:** The French E-Invoicing option is disabled because the customer is identified as a B2C partner when no VAT number is set. **Cause**: The B2C detection relies on the partner's VAT number instead of its SIREN/SIRET. As a result, French companies without a VAT number but with a valid SIREN are classified as B2C. **Fix**: Determine whether a partner is B2C based on the presence of a valid SIREN/SIRET (derived from `company_registry`) instead of the VAT number. This correctly identifies French business partners that are eligible for French e-Invoicing even when they do not have a VAT number configured. opw-6357756
Saudi electronic invoices issued in SAR no longer include a duplicate tax total in the XML sent to ZATCA. This prevents validation warnings or errors for common Saudi invoices and helps businesses process compliant e-invoices more reliably.
Original PR description
Steps to reproduce: - Create an invoice in a Saudi company (currency SAR) - Process it with ZATCA and review the generated XML file - ZATCA reports a validation error/notification for duplicate tax values, because the XML contains two cac:TaxTotal elements holding the same amount and currency Cause of the issue: _l10n_sa_get_additional_tax_total_vals always appended a second TaxTotal node regardless of the invoice's currency. this extra node is only valid when the invoice currency differs from the company's accounting currency (SAR). Since most Saudi invoices are issued in SAR (same as the company currency), the second TaxTotal was an exact duplicate of the first one's total amount. Solution: Only add the additional TaxTotal node when the invoice currency differs from the company currency opw-6409881 Forward-Port-Of: odoo/odoo#279929
This update ensures that invoices using the DIN5008 layout keep the recipient address in the correct position when sent by post through Snailmail. As a result, letters can now pass Pingen’s validation and be sent successfully instead of failing during delivery.
Original PR description
**Steps to reproduce:** - Install l10n_din5008 and accountant. - Enable Snailmail from Accounting → Settings. - Create a German customer (Fiscal Country: Germany). - Create and post a customer…
**Steps to reproduce:** - Install l10n_din5008 and accountant. - Enable Snailmail from Accounting → Settings. - Create a German customer (Fiscal Country: Germany). - Create and post a customer invoice using the DIN5008 report layout. - Select Send by Post. - Enable Developer Mode and navigate to `Settings → Technical → Email → Snailmail Letters`. - Open the generated letter and send it. **Current behavior:** The letter fails to be sent to Pingen with the following error: An error occurred when sending the document by post. Error: ` The attachment of the letter could not be sent. Please check its content and contact the support if the problem persists.` **Cause:** For Snailmail documents, Pingen validates that the recipient address is located within the DIN5008 address window. The current l10n_din5008 report renders additional document information instead of the address in the address area, preventing the compliance validation to fail. **Fix:** When rendering the report for Snailmail, ensure that only the recipient address is displayed in the DIN5008 address window while suppressing the additional information that would otherwise occupy this area. This preserves the standard DIN5008 layout for regular reports while generating a Snailmail-compliant PDF that passes Pingen’s validation. **Reference:** [Pignen Recipient Address Validation Rule](https://help.pingen.com/en/fix-and-enhance-letters/issue-with-recipient-address#040201) Ticket [link](https://www.odoo.com/odoo/project.task/6387869) opw-6387869
2 changes
Resolved issues and error corrections
Odoo now shows the specific error details returned by Serbia’s eFaktura service when an invoice submission fails. This helps users understand why an invoice was rejected and resolve issues faster instead of seeing only a generic connection or HTTP error.
Original PR description
**Steps to reproduce:** - Install the Serbian EDI module `l10n_rs_edi`. - Configure eFaktura credentials on the company. - Create and confirm a Serbian customer invoice. - Send the invoice to…
**Steps to reproduce:**
- Install the Serbian EDI module `l10n_rs_edi`.
- Configure eFaktura credentials on the company.
- Create and confirm a Serbian customer invoice.
- Send the invoice to eFaktura.
**Observed Behavior:**
When the eFaktura API returns an HTTP error, Odoo only displays the generic exception generated by `requests`, for example an HTTP 400/500 error.
The actual error information returned by eFaktura in the response body is not shown to the user, making it difficult to understand why the invoice was rejected.
**Cause:**
`_l10n_rs_edi_send` catches `HTTPError`, `Timeout`, and `ConnectionError`, but the error message is built only from the Python exception.
For HTTP errors, the eFaktura API may return a response containing more precise information such as:
```json
{
ErrorCode: ...,
Message: ...
}
```
This response was not being used when displaying the error in Odoo.
**Fix:**
When an HTTP response is available and contains an eFaktura error payload, use the returned `ErrorCode` and `Message` as the error displayed on the invoice. Fallback to the existing connection/HTTP exception message when no usable API response is available.
opw - 6453653This fix ensures that when an image already linked to another record is copied, Odoo reuses the existing attachment instead of creating an unnecessary duplicate. This helps keep the database cleaner and avoids extra storage and clutter behind the scenes.
Original PR description
Copying an image attachment already linked to another record could leave a redundant duplicate behind instead of reusing the existing one. opw-6463012