Daily updates from Odoo
Monday, October 27, 2025
194 changes
19 changes
Security fixes and vulnerability patches
This fix prevents users from bypassing approval-related restrictions when editing expense records. It helps protect approved expense sheets from unauthorized changes and keeps expense workflows compliant with expected access rights.
Original PR description
The state changes right check was only done on specific method but it wasn't check at write level. Which allowed to bypass it. The record rule on hr_expense_user without a check on the state is in draft allow to change data on approved expense sheets. forward port : #189360 Forward-Port-Of: odoo/odoo#217203 Forward-Port-Of: odoo/odoo#216850
Enhancements to existing features
This update adds practical improvements for stores using Six payment terminals, including end-of-day balance reporting, faster transaction handling, and support for refunds or reversals. It also improves receipt output and updates the terminal libraries, helping make payment operations smoother and more reliable.
Original PR description
Based on the feedback received from our partners we are missing some features in our Six terminal integration. This PR adds them 1. Send balance command to print end-of-day report 2. Adapt the code to reduce the sleep delay after each transaction 3. Refunds/payment reversals for Six + it also adds some minor code improvements like a) Card brand is now saved in pos payments instead of the card number b) Card number is still being sent to PoS and while not stored in v17 will be stored from v18 c) The code of ctypes_terminal_driver and Six Driver was improved to reuse the buffer size and improve the buffer usage d) Fixes the receipt size for the Six terminals e) updates the Six C libraries used to the latest version to get all the newest fixes Related C PR: https://github.com/odoo/worldline-lib/pull/9 Forward-Port-Of: odoo/enterprise#97962 Forward-Port-Of: odoo/enterprise#96748
Resolved issues and error corrections
Saving departure notes for archived employees no longer triggers an error. This prevents interruptions for HR users when maintaining employee records after departure.
Original PR description
Html fields are not part of the supported fields for tracking, see https://github.com/odoo/odoo/blob/11289fd128827587f6ed3fc5beed28f461c0e039/addons/mail/models/mail_tracking_value.py#L49 This causes a traceback when saving the `departure_description` on an archived employee. Added in https://github.com/odoo/odoo/commit/aa4d13b89b4497d2e5b33faa49ad86e0788782a2 Previous related fix: 9b723e2591224f2b563924d3b3dfe27ab909b7d0 opw-5140525
This fix prevents users from creating a new workplace directly from certain Swiss payroll forms when that shortcut could trigger an error. Users can still select existing workplaces, while avoiding a confusing failure during employee or contract setup.
Original PR description
The _rec_name was previously set to partner_id, causing type errors when typing a new workplace name in a Many2one field. Couldn't change it to anything else, as one should have to create a new field in that stable version and this is not the best practice. As a workaround, the corresponding field in the l10n_ch_hr_contract_views.xml is removed from it the quick_create to prevent the creation of new names on the fly. task-5043056 Forward-Port-Of: odoo/enterprise#96675 Forward-Port-Of: odoo/enterprise#93424
This fix prevents messaging and live chat screens from breaking when a channel member is loaded without full profile details. The system now safely falls back to an existing “unnamed” label, keeping conversations accessible in flows where member identity details are not needed.
Original PR description
Sometimes, channel members are received without their partner/guest because it's not important in the flow. However, some part of the JS code assume the persona is always set, resulting in errors. This PR guards access to persona when computing the member name, a fallback to "unnamed" is already in place. task-5184408 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#233056
Payroll now checks the correct document template separately for each payslip. This prevents cases where one payslip's missing or different template could affect others, helping ensure payroll documents are generated with the right layout.
Original PR description
Since the function that will return the template can return None in some cases, we need to check for each payslip what is the template. Forward-Port-Of: odoo/enterprise#97639
FedEx rate requests no longer fail when a customer's state or province code is longer than FedEx accepts. Odoo now skips that optional field when needed, helping users get shipping rates successfully for affected international addresses, including Belgian customers.
Original PR description
**Issue**: Sending a `stateOrProvinceCode` longer than 2 characters causes a FedEx error. **Steps to reproduce**: - Ensure the FedEx delivery carrier is installed. - Open the Sales application. - Create a new quotation with a Belgian customer whose state is set to `East Flanders`. - Click on "Add shipping". - Select "FedEx International" and click on "Get rate". - An error is raised. **Cause**: Some Odoo state codes are longer than 2 characters and are not covered by [this commit](https://github.com/odoo/enterprise/commit/38276c9a237a1779ce7a3e6f31102ff615691690). **Solution**: According to FedEx developer support, in such cases the `stateOrProvinceCode` field is not required. Therefore, we simply omit sending it when the code length is invalid. **Additional note** This commit also fixes 3 mistakes among the mandatory countries: - 3 for United Arab Emirates opw-4875939 Forward-Port-Of: odoo/enterprise#93642
Fixed an issue where partially paid subscription upsell orders could show a down payment invoice amount of zero. Down payment invoices now reflect the actual amount paid, improving billing accuracy and customer clarity.
Original PR description
Version- 17.0 ### Issue: - When an upsell order is partially paid (e.g., 10% of the original amount), the generated downpayment invoice incorrectly displayed an invoiced amount of 0. ### Steps to reproduce: - Make an Upsell order of subscription. - Update the condition of Online Payment from 100% to 10% (in this case). - Make the payment of 10% from portal view. - The invoice amount will be shown as $0. ### Fix: - Updated `_get_subscription_qty_to_invoice` to correctly determine the invoiced quantity and amount for downpayment invoices on upsell orders. ### Impact: - The downpayment invoices for upsell orders now correctly reflect the actual invoiced amount. Forward-Port-Of: odoo/enterprise#97412 Forward-Port-Of: odoo/enterprise#96719
Mobile self-order confirmations now keep the correct order selected after checkout. Customers see the right order number and the expected amount to pay at the counter, reducing confusion during repeat purchases.
Original PR description
…rmation **Steps to reproduce:** - Have a self order with the mobile setting (QR menu + self ordering) - Make a purchase, confirm it in the orders in the regular PoS - Make another purchase - The…
…rmation **Steps to reproduce:** - Have a self order with the mobile setting (QR menu + self ordering) - Make a purchase, confirm it in the orders in the regular PoS - Make another purchase - The order number did not increase and "Pay X at the counter" is not displayed **Why the fix:** Before this commit, on the confirmation page, we displayed the self order's current order, which was not correctly set in the case of a mobile self order. This is why we had the same order number (tracking_number) on the confirmation page. This is also why we did not display the "Pay X at the counter" part of the page, as the wrong order was chosen. With the current flow, the selectedOrderUuid was set to null after an rpc call, and was only set back if there was an open order and the current screen was different from confirmation. In this case, we had neither, because the current screen was confirmation and the function did not return any open order, as they are only considered open if they are older than the order we are currently working with. So with this, the selectedOrderUuid was set to null, just to stay like this. We then used the fallback in the currentOrder's getter (which works fine with the kiosk but not on mobile, and that's why it only works in kiosk), which gave us the wrong order (the last paid order). Right now, we do not set the selectedOrderUuid to null in the case where the current screen is the confirmation screen, as this seems to be the only issue we have with it. I couldn't find a way to test this, as we need to confirm the order from the regular PoS, then go back to the self order and make another sale. opw-5112561
This update corrects how notification preferences are checked for mail messages. Users should no longer receive duplicate push notifications for the same message when their inbox notification settings are applied.
Original PR description
**Current behavior before PR:** The `isInbox` condition was always evaluated as false because it incorrectly checked the user's notification preference in the wrong model. This caused users to receive two push notifications for the same message. **Desired behavior after PR is merged:** The `isInbox` condition now checks the user model for notification preferences, ensuring the correct behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Kiosk combo ordering now respects the specific product variants configured for a combo. This prevents customers from seeing unintended variant options or being charged extra prices that were not defined in the combo setup.
Original PR description
**Problem:** When we have a combo product that has a variant product, if we order it from the Kiosk, all the variants for that product will be displayed. The extra price will also be added, even…
**Problem:** When we have a combo product that has a variant product, if we order it from the Kiosk, all the variants for that product will be displayed. The extra price will also be added, even though it is not specified on the combo definition. **Steps to reproduce:** - Create a combo that has a variant product (like aluminium chair) - Go to the Kiosk and order said combo - In the combo page, click on the variant, all the possible variants are displayed **Why the fix:** When creating a combo, we should specify which product variant we want, so that only those are displayed on the combo selection page. The way it is done right now, every variant is displayed whether we want them or not, without a way to refrain them from being displayed. After this commit, if the variants are specified on the combo, only those are displayed in the Kiosk once we click on the combo. If we specify a product that has variants in the combo, all variants will still be displayed when clicking the product in the Kiosk, as it was before. opw-4924019 Forward-Port-Of: odoo/odoo#219908
German e-invoices now use the actual customer or parent company name when an invoice address has no contact name. This prevents labels like "Invoice Address" from appearing in XML invoice data when they are not shown on the customer-facing PDF.
Original PR description
**Steps to reproduce:** - Install Contacts, Accounting and l10n_de - Switch to a German company (e.g. DE Company) - Go to Contacts - Create a German contact with "XRechnung CIUS" as electronic format…
**Steps to reproduce:** - Install Contacts, Accounting and l10n_de - Switch to a German company (e.g. DE Company) - Go to Contacts - Create a German contact with "XRechnung CIUS" as electronic format - For this contact, create an "Invoice Address" without "Contact Name" - Create an invoice with the invoice address as customer - Confirm the invoice - Generate "XRechnung" via "Send & Print" button **Issue:** In the generated ULB XML and in factur-x.xml file embedded in the PDF, the customer name contains the mention "Invoice Address", which doesn't appear on the PDF of the invoice. **Cause:** The used invoice address has no name, so its "display_name" is build from the name of the parent contact and the type of the child contact (i.e. Invoice Address). **Solution:** Only use "display_name" of a contact if "name" is set. Otherwise fall back on "display_name" of the commercial partner. opw-5159291 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232819
Email Marketing templates using the showcase block now keep their separator styling after saving. This ensures recipients see emails as designed, improving visual consistency in campaigns.
Original PR description
Problem: When adding the `s_showcase` template in Email Marketing and saving, the separator is not properly rendered in the received email. Solution: Backport fix from `web_editor/convert_inline`: https://github.com/odoo/odoo/commit/7e3e6c1f42d97c2bb6830ed59dbec3a3b745d0c0 opw-5077992 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230773
Non-admin POS users can now select tax-free configurable products in branch company restaurants without seeing an access rights error. This helps sales staff complete orders smoothly and avoids interruptions when using product configurators.
Original PR description
**Issue:** In POS, clicking on a tax-free, inventory-tracked, configurable product as a non-admin user can throw an Access Rights error when trying to access it on a branch company's POS config. **Steps to reproduce:** - Configure a branching company on a parent company - Create a new POS restaurant on the child company - Create a configurable product that has no taxes associated with it and add it to a POS category so that it can be chosen from the POS screen - On a non-admin POS user, try to click that product 🐛 **Before this commit:** The user will get an Access Rights error. **After this commit:** The configurator dialog will load successfully. opw-5145176
Internal users who click the View Product button in product-related emails are now taken to the internal product page instead of the public shop page. This keeps staff workflows accurate while preserving the public shop redirect for portal and public users.
Original PR description
### Issue: Mail action redirects only to shop page, even though the user has internal access to the product page. #### To reproduce: 1- Create a db with website_sale installed. 2- Create a product and publish it. 3- In the product page chatter, send a message to an internal user 4- In received email, click on `View Product` button 5- As you see the shop page opens This is reproduced after #202555 Inside `_get_access_action`, if the product is published, we are returning `website_url`. We can add a check to do that only if user is portal or public. opw-5155281 Forward-Port-Of: odoo/odoo#233030 Forward-Port-Of: odoo/odoo#231961
When several Spanish invoices are sent to TicketBAI together, they are now processed in their posting order instead of the list selection order. This keeps the official chain numbering aligned with invoice chronology, reducing compliance errors and confusion.
Original PR description
Steps to reproduce: 1) Install l10n_es and l10n_es_edi_tbai. 2) Create a Spanish contact with a valid address and NIF. 3) Create several customer invoices and confirm (post) them. 4) From the list…
Steps to reproduce: 1) Install l10n_es and l10n_es_edi_tbai. 2) Create a Spanish contact with a valid address and NIF. 3) Create several customer invoices and confirm (post) them. 4) From the list view, select them and send to TicketBAI. 5) The TicketBAI “chain index” is inverted: the newest invoice gets the smallest index and the oldest gets the largest. The first invoice in the legal/chronological sequence is not index 1. Current behavior: - When sending multiple invoices at once, the processing loop uses the batch order as-is, which (from the list view) often arrives in reverse chronological order. The chain index is assigned incrementally based on that order, yielding an inverted chain (newest=1, oldest=N). Expected behavior: - The TicketBAI chain index must follow issuance/confirmation chronology: the oldest posted invoice in the batch is index 1, then 2, … up to the newest. Technical reason: - `_call_web_service_before_invoice_pdf_render` iterates `invoices_data.items()` without an explicit ordering by confirmation (posting) date. Depending on how the selection is built, items are processed newest-first, so the computed `chain_index` is reversed. Solution: - Sort the invoices before sending by posting date (`move.date`) ascending, with fallbacks to `invoice_date` and `create_date`, and a deterministic tiebreaker by `id`. Process sequentially after sorting and keep the per-invoice commit. opw-[5072667](https://www.odoo.com/odoo/my-tasks/5072667) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229736
This fixes an issue where warehouse users could be blocked from validating a partial package transfer for products valued and tracked by lot or serial number. The system now avoids raising an incorrect missing lot error when the lot information is already present, helping barcode-based transfers complete reliably.
Original PR description
**Problem:** With a valued by lot/SN product, assigning a partial barcode move line to a new package will trigger a lot error when validating even if there is a lot on the line. **Steps to…
**Problem:** With a valued by lot/SN product, assigning a partial barcode move line to a new package will trigger a lot error when validating even if there is a lot on the line. **Steps to reproduce:** - Create product tracked by lot and valued by lot/SN. - Set on on hand quantity of 100 in stock with a package that you create and a lot that you create. - Create an internal transfer for 100 of this product. - Mark it as to do. - Open it in barcode. - Scan stock. - Scan the package. - Edit the line to quantity of 50. - Scan any other empty package already existing to set it as the delivery package. - Validate. - On the incomplete transfer widget, also click on validate. **Current behavior:** An error 'Lot/Serial number is mandatory for product valuated by lot' is triggered even though there is a lot on the line. **Cause of the issue:** When _assignEmptyPackage() is called to assign the new package, it calls shouldsplitline() which returns true because line.qty_done is smaller thant line.reserved_uom_qty https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/stock_barcode/static/src/models/barcode_picking_model.js#L949-52 Therefore, splitLine() is called and a new line is created with no package and no lot. Then, when we validate, _action_done() is called on the move which calls _action_done() on the move lines. https://github.com/odoo/odoo/blob/30189db8a47e69038242a68706cfdfe6c152e779/addons/stock/models/stock_move.py#L2065 In the stock_account override, the error is raised for the line newly created because it has no lot_id and no lot_name. https://github.com/odoo/odoo/blob/30189db8a47e69038242a68706cfdfe6c152e779/addons/stock_account/models/stock_move_line.py#L90-L91 opw-5028008 Forward-Port-Of: odoo/odoo#231482
Contact addresses now include the second street address line when generating the complete address. This ensures emails and other documents show the full address for contacts who use an additional address line.
Original PR description
Issue: If a user with `street2` wants to utilize the `contact_address_complete` field, the `street2` field is not included. Purpose of this PR: To include the `street2` field in the `contact_address_complete` Steps to reproduce on Runbot: install contact fill in a contact's `street2` create email template that uses the `contact_address_complete` `street2` is omitted from the complete address opw-5186218 Forward-Port-Of: odoo/enterprise#98103
Signing an offer as the responsible HR no longer fails when an employee requested extra time off and automatic allocation is enabled. This ensures the salary package workflow can be completed smoothly without blocking HR users.
Original PR description
- When the employee requested extra time off, and the automatic allocation setting was turned on, signing the offer as the responsible HR caused an error. Task-5022631 Forward-Port-Of: odoo/enterprise#98060 Forward-Port-Of: odoo/enterprise#92663
22 changes
Security fixes and vulnerability patches
This update prevents employees from changing approved expense sheets by bypassing normal permission checks. It strengthens control over expense approvals so finalized records remain protected from unauthorized edits.
Original PR description
The state changes right check was only done on specific method but it wasn't check at write level. Which allowed to bypass it. The record rule on hr_expense_user without a check on the state is in draft allow to change data on approved expense sheets. forward port : #189360 Forward-Port-Of: odoo/odoo#217203 Forward-Port-Of: odoo/odoo#216850
Enhancements to existing features
This update makes the accounting tax calculation helper automatically extract records from the grouping key. It reduces manual handling for developers working on tax aggregation, making related accounting screens and calculations easier to maintain.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231947
Resolved issues and error corrections
This update improves the accounting tax helpers used when preparing complex product scenarios such as discounts, down payments, and combo products. It makes tax recalculations more predictable and fixes edge cases where tax details could be incomplete or incorrectly handled.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Non-admin purchase users can now use the Purchase Order Suggest wizard without being blocked by an access error. The fix saves suggestion preferences as user-specific settings instead of trying to create administrator-only global defaults, keeping purchasing workflows moving for regular staff.
Original PR description
**Issue:** Non-admin users get an AccessError as follows ```doesn't have 'create' access to: - Default Values, Based on (Purchase Order Suggest) (ir.default: 45)... ``` when using the Purchase Order…
**Issue:** Non-admin users get an AccessError as follows ```doesn't have 'create' access to: - Default Values, Based on (Purchase Order Suggest) (ir.default: 45)... ``` when using the Purchase Order Suggest wizard. **Cause:** The `ir_default_user_rule` record rule restricts non-admin users to only create/modify ir.default records where `user_id = user.id` However, in `_save_values_for_vendor` method: https://github.com/odoo/odoo/blob/6b8a8196c63275eead6709bb20002df0be12a059/addons/purchase_stock/wizard/purchase_order_suggest.py#L199-L204 `ir.default.set()` is called without setting the `user_id` parameter, which defaults to an attempt to create a global default: what only admins can do. **Steps to reproduce:** - create a non-admin user with purchase user permissions. - log in as that user and create a Purchase Order - add products to the catalog and click "Suggest. - configure suggest parameters and click "Compute" (Note: compute is only enabled when estimated_price > 0) An AccessError occurs opw-5076647
This fixes an inventory validation error that could block warehouse users when moving only part of a package for products tracked and valued by lot or serial number. Transfers now recognize the existing lot information correctly, reducing unnecessary interruptions in barcode-based stock operations.
Original PR description
**Problem:** With a valued by lot/SN product, assigning a partial barcode move line to a new package will trigger a lot error when validating even if there is a lot on the line. **Steps to…
**Problem:** With a valued by lot/SN product, assigning a partial barcode move line to a new package will trigger a lot error when validating even if there is a lot on the line. **Steps to reproduce:** - Create product tracked by lot and valued by lot/SN. - Set on on hand quantity of 100 in stock with a package that you create and a lot that you create. - Create an internal transfer for 100 of this product. - Mark it as to do. - Open it in barcode. - Scan stock. - Scan the package. - Edit the line to quantity of 50. - Scan any other empty package already existing to set it as the delivery package. - Validate. - On the incomplete transfer widget, also click on validate. **Current behavior:** An error 'Lot/Serial number is mandatory for product valuated by lot' is triggered even though there is a lot on the line. **Cause of the issue:** When _assignEmptyPackage() is called to assign the new package, it calls shouldsplitline() which returns true because line.qty_done is smaller thant line.reserved_uom_qty https://github.com/odoo/enterprise/blob/931779b845291e1dc7efdea91d91bdfa5ab703d6/stock_barcode/static/src/models/barcode_picking_model.js#L949-52 Therefore, splitLine() is called and a new line is created with no package and no lot. Then, when we validate, _action_done() is called on the move which calls _action_done() on the move lines. https://github.com/odoo/odoo/blob/30189db8a47e69038242a68706cfdfe6c152e779/addons/stock/models/stock_move.py#L2065 In the stock_account override, the error is raised for the line newly created because it has no lot_id and no lot_name. https://github.com/odoo/odoo/blob/30189db8a47e69038242a68706cfdfe6c152e779/addons/stock_account/models/stock_move_line.py#L90-L91 opw-5028008 Forward-Port-Of: odoo/odoo#231482
This fix ensures Spanish TicketBAI submissions assign the legal chain order based on when invoices were posted, rather than the order they were selected in a list. It prevents batches from being sent with newest invoices first, helping maintain compliant chronological invoice sequencing.
Original PR description
Steps to reproduce: 1) Install l10n_es and l10n_es_edi_tbai. 2) Create a Spanish contact with a valid address and NIF. 3) Create several customer invoices and confirm (post) them. 4) From the list…
Steps to reproduce: 1) Install l10n_es and l10n_es_edi_tbai. 2) Create a Spanish contact with a valid address and NIF. 3) Create several customer invoices and confirm (post) them. 4) From the list view, select them and send to TicketBAI. 5) The TicketBAI “chain index” is inverted: the newest invoice gets the smallest index and the oldest gets the largest. The first invoice in the legal/chronological sequence is not index 1. Current behavior: - When sending multiple invoices at once, the processing loop uses the batch order as-is, which (from the list view) often arrives in reverse chronological order. The chain index is assigned incrementally based on that order, yielding an inverted chain (newest=1, oldest=N). Expected behavior: - The TicketBAI chain index must follow issuance/confirmation chronology: the oldest posted invoice in the batch is index 1, then 2, … up to the newest. Technical reason: - `_call_web_service_before_invoice_pdf_render` iterates `invoices_data.items()` without an explicit ordering by confirmation (posting) date. Depending on how the selection is built, items are processed newest-first, so the computed `chain_index` is reversed. Solution: - Sort the invoices before sending by posting date (`move.date`) ascending, with fallbacks to `invoice_date` and `create_date`, and a deterministic tiebreaker by `id`. Process sequentially after sorting and keep the per-invoice commit. opw-[5072667](https://www.odoo.com/odoo/my-tasks/5072667) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229736
FedEx rate requests now skip state or province codes when they are too long for FedEx to accept, preventing errors for customers such as those in Belgium. The update also corrects FedEx country requirements for the United Arab Emirates, improving shipping reliability.
Original PR description
**Issue**: Sending a `stateOrProvinceCode` longer than 2 characters causes a FedEx error. **Steps to reproduce**: - Ensure the FedEx delivery carrier is installed. - Open the Sales application. - Create a new quotation with a Belgian customer whose state is set to `East Flanders`. - Click on "Add shipping". - Select "FedEx International" and click on "Get rate". - An error is raised. **Cause**: Some Odoo state codes are longer than 2 characters and are not covered by [this commit](https://github.com/odoo/enterprise/commit/38276c9a237a1779ce7a3e6f31102ff615691690). **Solution**: According to FedEx developer support, in such cases the `stateOrProvinceCode` field is not required. Therefore, we simply omit sending it when the code length is invalid. **Additional note** This commit also fixes 3 mistakes among the mandatory countries: - 3 for United Arab Emirates opw-4875939 Forward-Port-Of: odoo/enterprise#93642
Sale orders that use only fixed taxes no longer fail when read through XML-RPC integrations. This prevents export or integration errors by ensuring tax total values are returned in a format the system can safely transmit.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Create a fixed tax; 2. create a sale order using only the fixed tax; 3. read the sale order via XML-RPC. Issue ----- TypeError: cannot marshal None unless allow_none is enabled Cause ----- If only a fixed tax is used, the `_get_tax_totals_summary` method returns a dict where the `display_base_amount_currency` and `display_base_amount` values are `None`, leading to an error serializing the result. Solution -------- As the result gets serialized by `OdooMarshaller(allow_none=False)`[^1], we should use `False` instead of `None`. [^1]: https://github.com/odoo/odoo/blob/b887bf2/odoo/addons/base/controllers/rpc.py#L114 opw-5173477 Forward-Port-Of: odoo/odoo#232517
Draft sales orders now let users click product lines to edit the product or add a description instead of unexpectedly opening the product record. This reduces friction when updating quotes and prevents confusion during routine sales order edits.
Original PR description
Versions -------- - saas-18.3+ Steps ----- 1. Create a sales order; 2. add a product that doesn't have an extra description; 3. save & exit view; 4. go back to view; 5. add a description or change the product on the line. Issue ----- Clicking on the product field opens the product record instead of edit mode. Cause ----- It opens the product record because the `canOpen` property is set to `true`. As this is the default value, and isn't getting changed anywhere, the line will always open the product record outside of edit mode. Solution -------- Instead of using OR, check `props.canOpen` AND additional checks. opw-5172115
This change removes redundant database checks from mail link previews because existing required-field rules already cover them. It helps avoid restore problems when moving database dumps between PostgreSQL versions, though existing databases may still need cleanup before restore.
Original PR description
Same as #229274 these constraints are redundant with `required=True` and cause issues when restoring a dump from pg17 to pg18. And much like #229274 this only fixes databases going forward, on existing databases the constraints have to be dropped on the source.
Bank reconciliation models now correctly match rules that exclude specific text from labels, even when some transaction fields are empty. This helps accountants rely on automated reconciliation rules more consistently and reduces missed matches during bank statement processing.
Original PR description
Currently bank reconciliation model match only the label type “Contains” The “not contain” type is not working Steps to reproduce: - Open Accounting Dashboard - Access Bank journal reconciliation models (3dots > Models) - Open a [Model] and set: - Label "Not Contains" "Test" - Add a Bank Statement with any label Issue: [Model] won't match Analysis: This occurs because in case the payment_ref or transaction_details contains a NULL value the ILIKE operations will evaluate to NULL, not TRUE or FALSE. Any other comparison involving NULL value will result in NULL and the whole condition will fail opw-5065006 [Task link](https://www.odoo.com/odoo/project/49/tasks/5065006)
This fixes an issue in Email Marketing where separators in the showcase email template could appear incorrectly after saving. Recipients should now see the intended email layout, helping campaigns look more polished and consistent.
Original PR description
Problem: When adding the `s_showcase` template in Email Marketing and saving, the separator is not properly rendered in the received email. Solution: Backport fix from `web_editor/convert_inline`: https://github.com/odoo/odoo/commit/7e3e6c1f42d97c2bb6830ed59dbec3a3b745d0c0 opw-5077992 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230773
This fixes an issue where Odoo could lose a user's own presence channel when some pages did not provide the database name to the websocket connection. Users should now receive more consistent presence updates across browser tabs and sessions, reducing incorrect online/offline status behavior.
Original PR description
The websocket worker holds a single WebSocket connection per browser. Clients pass the current user ID and DB name, which the worker uses to detect login/logout. Some pages omit the DB name, causing…
The websocket worker holds a single WebSocket connection per browser. Clients pass the current user ID and DB name, which the worker uses to detect login/logout. Some pages omit the DB name, causing the worker to incorrectly mark the user as changed. This clears previous channels, which may never be added back. This is particularly noticeable with presence channels: the user's own channel can be lost, preventing them from receiving their own presence updates (e.g. when another browser closes, the user cannot see they are disconnected and cannot correct the value). The user's own presence channel should be added server-side, so the first subscription immediately returns the user presence and the DB should not be taken into account if ommited. task-5096212 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#233141 Forward-Port-Of: odoo/odoo#232984
Fixed a Point of Sale issue where clicking details within an order line could open and immediately close the numpad. Cashiers can now select order line details, such as eWallet balance information, without losing access to the numpad.
Original PR description
Steps to reproduce: =================== - Click on an orderline - Then click on a detail inside it (e.g., eWallet Balance line) - The numpad first opens and then closes right away Issue: ====== - Clicking on a detail inside the orderline makes the numpad open and close at the same time - This makes it impossible to use the numpad properly Cause: ====== - The click from the child element also reaches the main orderline click - Because of this, the numpad gets two clicks (open and close) Fix: ==== - Added `stopPropagation` in the click handler to block event bubbling - Now the numpad only reacts once and stays open as expected Task: 5000327 Forward-Port-Of: odoo/odoo#232197 Forward-Port-Of: odoo/odoo#227675
This fix ensures payslips correctly show worked days for employees on fully flexible contracts, even when no standard work calendar is assigned. Payroll teams can now rely on attendance or planning-based work entries appearing correctly, reducing blank payslip sections and manual corrections.
Original PR description
**Issue:** Payslips show blank worked days for employees with contracts without a `resource_calendar_id` (fully flexible, despite having valid work entries **Cause:** `_get_worked_day_lines()` skips worked day computation if the contract has no calendar https://github.com/odoo/enterprise/blob/1a10e0444fdb71a072262a1f14f0bfc766d109c6/hr_payroll/models/hr_payslip.py#L665-L674 **Steps to Reproduce:** - Assign an employee a fully flexible contract with attendance as work entry source. - Create work entries based on the attendance records of the employee record - Go to employees > contracts > new Payslip Worked Days section is empty, even though attendance shifts are showing up on top. **Fix:** removing the calendar requirement in the main method and adding a fallback calendar in the called utility method **Note:** same issue happens if work entry source of the contract is Planning opw-4931972 Forward-Port-Of: odoo/enterprise#93935
Fixed an issue where internal users clicking a product link from an email were sent to the public shop page instead of the product record they can access. This helps staff reach the correct product page directly from email notifications while keeping public and portal users on the website view.
Original PR description
### Issue: Mail action redirects only to shop page, even though the user has internal access to the product page. #### To reproduce: 1- Create a db with website_sale installed. 2- Create a product and publish it. 3- In the product page chatter, send a message to an internal user 4- In received email, click on `View Product` button 5- As you see the shop page opens This is reproduced after #202555 Inside `_get_access_action`, if the product is published, we are returning `website_url`. We can add a check to do that only if user is portal or public. opw-5155281 Forward-Port-Of: odoo/odoo#233030 Forward-Port-Of: odoo/odoo#231961
Fixes an issue where HR users could encounter an error when signing an offer for an employee who requested extra time off with automatic allocation enabled. This helps keep the offer acceptance process smooth and prevents disruption in salary package workflows.
Original PR description
- When the employee requested extra time off, and the automatic allocation setting was turned on, signing the offer as the responsible HR caused an error. Task-5022631 Forward-Port-Of: odoo/enterprise#98060 Forward-Port-Of: odoo/enterprise#92663
This update fixes a failing automated test related to chat message bubbles in the Discuss area. It helps keep release validation stable without changing how users interact with the application.
Original PR description
Backport of fix https://github.com/odoo/odoo/pull/227445 Fixes runbot-error-233607 Forward-Port-Of: odoo/odoo#233243
The complete contact address now includes the second street address line when it is filled in. This ensures emails and templates using the full address show complete and accurate contact information.
Original PR description
Issue: If a user with `street2` wants to utilize the `contact_address_complete` field, the `street2` field is not included. Purpose of this PR: To include the `street2` field in the `contact_address_complete` Steps to reproduce on Runbot: install contact fill in a contact's `street2` create email template that uses the `contact_address_complete` `street2` is omitted from the complete address opw-5186218 Forward-Port-Of: odoo/enterprise#98103
This fixes a loophole that allowed users to change tax report results by adding tax tags to old journal items after the tax lock date. The system now blocks those changes as expected, helping preserve locked tax filings and reporting accuracy.
Original PR description
Despite the tax lock date, users are able to modify the tax report by adding tags.
**Steps to reproduce:**
Ensure the tax lock date is set
1. Journal Items list view
2. Edit one/many lines that
- have a date before the tax lock date,
- don't have a tax,
- nor tax tags,
- and is not a tax line.
3. Add a new tax tag
**Issue:**
The tax tags are added and might impact a tax report, when you should have received a user error.
**Cause:**
The `write` function calls the `_check_tax_lock_date` which in turn only checks the existing line instead of the values given in the `write` parameters. Since the line has no existing tax tags the check does not fail.
**Solution:**
Call the tax lock check both before and after writing the move line.
Task-5169152
Forward-Port-Of: odoo/odoo#233032
Forward-Port-Of: odoo/odoo#232380Code cleanup and technical improvements
This update simplifies automated test files by removing unnecessary wrapper labels that duplicated file names or could be misleading. It does not change business features, but makes the test suite easier for developers to read and maintain, supporting safer future updates.
Original PR description
This commit removes test files using a single 'describe' call to wrap its tests, with a name being either redundant with the test file itself or is too misleading.
Regular expression used to find isolated suites:
```js
/^\s*import.*(?:\n(?!describe\()(?!test\().*)+\ndescribe\("[\w\s.]+",.*(?:\n(?!describe\().*)+\n\}\);\n(?!\n)/
```
Tip for reviewers: tick **"Hide whitespace"** when reviewing diff
<img width="237" height="205" alt="image" src="https://github.com/user-attachments/assets/373f7cc6-5e0e-4599-968a-39aad8fac2f0" />
Enterprise: https://github.com/odoo/enterprise/pull/98046
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#233155
Forward-Port-Of: odoo/odoo#233006This update simplifies several automated test files by removing unnecessary grouping labels that duplicated or confused the file names. It does not change product behavior, but it makes the test suite easier for developers to review and maintain across affected business areas.
Original PR description
This commit removes test files using a single 'describe' call to wrap its tests, with a name being either redundant with the test file itself or is too misleading.
Regular expression used to find isolated suites:
```js
/^\s*import.*(?:\n(?!describe\()(?!test\().*)+\ndescribe\("[\w\s.]+",.*(?:\n(?!describe\().*)+\n\}\);\n(?!\n)/
```
Tip for reviewers: tick **"Hide whitespace"** when reviewing diff
<img width="237" height="205" alt="image" src="https://github.com/user-attachments/assets/373f7cc6-5e0e-4599-968a-39aad8fac2f0" />
Community: https://github.com/odoo/odoo/pull/233006
Forward-Port-Of: odoo/enterprise#98137
Forward-Port-Of: odoo/enterprise#980463 changes
Resolved issues and error corrections
This fixes an error that occurred when an employee requested extra time off and automatic allocation was enabled. HR teams can now sign offers as the responsible HR user without the process failing, improving reliability in salary package workflows.
Original PR description
- When the employee requested extra time off, and the automatic allocation setting was turned on, signing the offer as the responsible HR caused an error. Task-5022631 Forward-Port-Of: odoo/enterprise#97996 Forward-Port-Of: odoo/enterprise#92663
Belgian companies connecting to CodaBox can now use their company registry number when their VAT number is marked as not applicable. This prevents connection issues for non-taxable companies and keeps the setup flow consistent with companies that leave the VAT field empty.
Original PR description
If a company is not subject to taxes, they may not have a VAT number. In that case, the field can be left empty, such that the Company Registry is used instead for the CodaBox connection. However, the case where "/" (Non Applicable) was used as the VAT number was handled. This commit now handles VAT="/" in the same way it handles no VAT at all by using the company registry as a fallback. The commit also cleans up how the company ID is used to avoid duplicated code by creating a computed field. opw-5164155 Forward-Port-Of: odoo/enterprise#98025
The complete contact address now includes the second street address line when it is filled in. This ensures emails, templates, and other outputs using the complete address show the full customer or partner address correctly.
Original PR description
Issue: If a user with `street2` wants to utilize the `contact_address_complete` field, the `street2` field is not included. Purpose of this PR: To include the `street2` field in the `contact_address_complete` Steps to reproduce on Runbot: install contact fill in a contact's `street2` create email template that uses the `contact_address_complete` `street2` is omitted from the complete address opw-5186218 Forward-Port-Of: odoo/enterprise#98103
27 changes
Security fixes and vulnerability patches
This update prevents users from bypassing approval-stage restrictions on expense records. It helps protect approved expense sheets from unauthorized changes and keeps expense controls consistent.
Original PR description
The state changes right check was only done on specific method but it wasn't check at write level. Which allowed to bypass it. The record rule on hr_expense_user without a check on the state is in draft allow to change data on approved expense sheets. forward port : #189360 Forward-Port-Of: odoo/odoo#217203 Forward-Port-Of: odoo/odoo#216850
New functionality added to Odoo
Users can now upload e-Receipt XML files exported from the Nilvera Portal directly from the Receipts list. Odoo creates draft receipts from the uploaded files and opens the resulting records, reducing manual entry for Turkish e-dispatch workflows.
Original PR description
This PR introduces a new option to import e-Receipt XML files exported from the Nilvera Portal. - An "Upload e-Receipt (XML)" button is now added in the list view of Receipts (stock picking). - Upon upload, draft receipts are created based on the XML data. - After successful import, the user is redirected to a new view displaying the generated receipts. TaskID:4452521 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231908 Forward-Port-Of: odoo/odoo#217530
Enhancements to existing features
When importing a data module fails, users now see the full error details instead of only the final part of the message. This makes it easier to understand what went wrong or share complete information with support for faster troubleshooting.
Original PR description
Before this commit, when an error happens during the import of a data module, the UserError was displaying the last part of the traceback. In some cases, it was sufficient (missing manifest, unknown dependency, ...). But in other cases, this was only displaying the record triggering the error, but not more, giving no clue on what was the exact error and how to fix it. This commit adapts the UserError to provide the full traceback in the popup window, such that the user can understand or at least report the error. Another task is targeting master to improve the design of this window. task-4876416
The Peppol integration now follows OpenPeppol’s preferred capitalization across user-facing labels. It also removes the Peppol status from the customer invoice list view, reducing visual clutter while keeping the underlying Peppol functionality available elsewhere.
Original PR description
1. Align naming PEPPOL -> Peppol. This is the directive from OpenPeppol for few years already in all their communications. 2. Remove the PEPPOL status from the `account.move` list view. task-none (FP feedback for point 2)
Resolved issues and error corrections
This fixes a website shop test that could fail when multiple websites are configured with different domain settings. The change makes the test use the intended default website, improving reliability without changing customer-facing behavior.
Original PR description
Why? ==== -When a domain value is set, get_current_website may return a different website ID than the default one. In this case, the domain of the other website is False, causing a failure when trying to check if a boolean exists within a string. Fix === - Use directly the default website. runbot-233387 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The checkout test for Ecuador address flows now waits until the page interaction is ready before moving to billing details. This helps avoid false failures in automated checks, improving confidence in website sales quality without changing customer-facing behavior.
Original PR description
This commit add wait for intreaction to be ready before moving to billing step which render billing container conditionally depending on toggle from interaction. runbot-231718
Fixed an issue where changing rental dates in the online cart could shift the layout and make quantity buttons stop working. Customers can now adjust rental periods without disrupting the cart experience or losing access to key actions.
Original PR description
Steps to reproduce: =================== 1. Add a meeting product to the cart with the "Rental" option checked. 2. Go to the cart and change the date range. → The cart layout shifts to the left, and…
Steps to reproduce: =================== 1. Add a meeting product to the cart with the "Rental" option checked. 2. Go to the cart and change the date range. → The cart layout shifts to the left, and quantity buttons become unclickable. Cause: ====== Two separate issues caused this behavior: 1. **Layout shift:** When updating the date range, `cart_quantity` can be undefined. The logic that determines whether to toggle the `col-lg-7` class relies on this value. When undefined, it incorrectly assumes the cart is empty and shifts the layout to the left. 2. **Unclickable buttons:** The following line replaces the entire `.js_cart_lines` element: https://github.com/odoo/odoo/blob/abf9bc083c5a219a0b6fc0346dcd2a2cb503e081/addons/website_sale/static/src/js/website_sale_utils.js#L88 This removes all old elements (and their event listeners) and inserts new ones from the server. As a result, interactive buttons (e.g., quantity update) lose their functionality. Older versions didn't face this issue because they used jQuery event delegation, which automatically handled dynamic elements. Solution: ========= 1. provide the cart_quantity value via the controller, 2. Restart the cart interaction after re-rendering to restore event bindings for clickable buttons. opw-5167866
This fixes an issue where the showcase email template could lose or misrender its separator after saving in Email Marketing. Recipients should now see the intended visual layout, helping marketing emails look consistent and professional.
Original PR description
Problem: When adding the `s_showcase` template in Email Marketing and saving, the separator is not properly rendered in the received email. Solution: Backport fix from `web_editor/convert_inline`: https://github.com/odoo/odoo/commit/7e3e6c1f42d97c2bb6830ed59dbec3a3b745d0c0 opw-5077992 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#232565 Forward-Port-Of: odoo/odoo#230773
Managers can now create employee appraisals as expected. This fixes an access-related issue in the Appraisals app and adds test coverage to help prevent the problem from returning.
Original PR description
fixed with https://github.com/odoo/enterprise/commit/d4b708d22c0c3768cbb50bd5a43e91db419ff277 added test to cover the use case opw-4794641 Forward-Port-Of: odoo/enterprise#87831
Fixed an issue that caused the stock valuation screen to crash when Arabic was enabled. This ensures users working in Arabic can access inventory valuation information without interruption.
Original PR description
Steps to reproduce the bug:
- activate Arabic language
- Try to open stock valuation
Traceback is triggered:
raise ValueError("time data %r does not match format %r" % ValueError: time data '٢٠٢٥-١٠-٢٢' does not match format '%Y-%m-%d'
opw-5176859The accounting settings no longer show the "Enable Auto Transfers" option because it pointed to an old module name and did not work when users tried to save it. Users who need this capability can still install the Account Transfers app directly, avoiding a confusing setting that appeared to do nothing.
Original PR description
### Steps to reproduce: - Install "account_accountant" - Go in the settings - Search for "Enable Auto Transfers", tick the option - Save - The option is not ticked ### Cause: This option is supposed to install the module for Account Transfers. The option field is called `module_account_auto_transfer`. It's supposed to install the module `account_auto_transfer`. But this module was [refactored in 19.0](https://github.com/odoo/enterprise/commit/77c248981c9e1ccbb5d4c88a0915a231f040df84) and renamed `account_transfer`. So the settings can't find the module to install, nothing happen, and the option stays the same. ### Solution: Hide the option in 19.0. To respect the stable, we cannot rename a stored field. This is not a very important loss, the users can install the module `account_transfer` directly from the Apps application. Give the variable the correct name (`module_account_transfer`) in master. opw-5149342
The Point of Sale automated test was adjusted to skip an unreliable closing step that often failed when many add-ons were installed. This reduces false failures in validation runs and helps teams get faster, more dependable feedback.
Original PR description
fix runbot error on generic pos tour runbot-233183
Email buttons for published products now send internal users to the product record they can access, instead of always opening the public shop page. This prevents confusion for staff using product chatter emails while keeping public and portal users on the website shop experience.
Original PR description
### Issue: Mail action redirects only to shop page, even though the user has internal access to the product page. #### To reproduce: 1- Create a db with website_sale installed. 2- Create a product and publish it. 3- In the product page chatter, send a message to an internal user 4- In received email, click on `View Product` button 5- As you see the shop page opens This is reproduced after #202555 Inside `_get_access_action`, if the product is published, we are returning `website_url`. We can add a check to do that only if user is portal or public. opw-5155281 Forward-Port-Of: odoo/odoo#233030 Forward-Port-Of: odoo/odoo#231961
This fixes an issue where changing the heading style of website titles, such as shop or cart headers, could make the text disappear. Website editors can now adjust header styles without risking accidental content loss.
Original PR description
Problem: When trying to change the header type of "All products" in the "/shop" page on Website, the title disappears. Cause: The title is `h1[data-oe-field]`. When we update it, we replace the node with a new header node. This triggers `handleMutations` with both the removed node and the new node. The old removed node with no content is processed in `normalizeHandler`, which causes removal of the content from the new node as well. Solution: In `FieldChangeReplicationPlugin.handleMutations`, filter out removed nodes so they are not processed in `normalizeHandler`. Steps to reproduce: 1. Enter Website. 2. Go to the cart and select the header "Order Summary". 3. Attempt to change the font style (Header 1, Header 2, etc.). → The header disappears. opw-5106712 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229486
This update makes automated tests for two-factor authentication more stable by removing timing-sensitive steps and waiting for clearer success signals. It helps reduce false test failures under heavy load, improving confidence in release validation without changing the user-facing feature.
Original PR description
- Remove timing-sensitive check on modal closed, wait for the row to be deselected instead (this assumes the list view has been reloaded and can be interacted with again, whereas the security check modal is closed before we actually run the action) (?). - Replace odd and somewhat brittle `run()` functions by equivalent (or better) triggers, with or without ~~you~~ clicks. - Replace a few waits on modals closed by waits on the corresponding notification appearing, this is likely more reliable. Locally this looks to be making the totp tours a *lot* more reliable under load, hopefully this also works on runbot: this aims to solve a jumble of uncommon non-deterministic errors: - https://runbot.odoo.com/odoo/error/161302 - https://runbot.odoo.com/odoo/error/107908 - https://runbot.odoo.com/odoo/error/161302 - https://runbot.odoo.com/odoo/error/233265 - https://runbot.odoo.com/odoo/error/233513 Forward-Port-Of: odoo/odoo#232986 Forward-Port-Of: odoo/odoo#232958
Self-ordering now handles shared table QR codes differently depending on the payment flow. Customers paying separately no longer see or change each other’s orders, while pay-after-meal tables can still build one shared order together.
Original PR description
Before this commit orders were always shared between multiple devices using the same QR code. This could lead to issues when multiple customers were using self-ordering at the same table, as they could see and modify each other's orders. When multiple devices are used for self-ordering with the same QR code, there is now two mode possible: - Pay after each: orders are not shared, and the table isn't linked to the order when synchronizing. Instead the table number is in the floating order name. - Pay after meal: orders are shared, and the table is linked to the order when synchronizing. That's means that multiple devices can add products to the same order. taskId: 5187089 Forward-Port-Of: odoo/odoo#232659
Incoming emails sent to a project alias with duplicate address formats, such as a plain address plus a display name, no longer cause task creation to fail. This prevents affected emails from bouncing and helps teams reliably create project tasks from customer messages.
Original PR description
Description of the issue/feature this PR addresses: Task creation from incoming emails fails when the “To” header contains RFC-compliant email formats with display names, for example:…
Description of the issue/feature this PR addresses: Task creation from incoming emails fails when the “To” header contains RFC-compliant email formats with display names, for example: `support@company.com, "Support Team" <support@company.com>` Odoo interprets this as two separate email addresses. When processing, the system attempts to remove the project alias (`support@company.com`) from `unmatched_partner_emails` multiple times, which causes the error: `ValueError: list.remove(x): x not in list` Current behavior before PR: - Incoming emails with display names in the “To” field cause a `ValueError` in `project_task.py`. - Task creation via project alias fails and the email bounces. Desired behavior after PR is merged: - The system checks whether the alias email exists in the list before attempting to remove it. - No crash occurs, and task creation works correctly for emails with display names. Fix implemented: - Added a conditional check in `addons/project/models/project_task.py` before removing the alias address. - This ensures safe removal and prevents the `ValueError`. Fixes: #233133 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Invoice section and subsection behavior has been cleaned up so PDF invoices are easier to read and totals are calculated correctly. Users can no longer select conflicting display options that produced unreadable invoices, and section indentation is improved across layouts.
Original PR description
Few fixes for section and subsection feature. 1. Simplify the colspan calculation by removing the get_column_to_exclude_for_colspan_calculation Python method and performing all calculations in XML.…
Few fixes for section and subsection feature.
1. Simplify the colspan calculation by removing the get_column_to_exclude_for_colspan_calculation
Python method and performing all calculations in XML. This change makes it simpler to override
the behavior.
2. Add padding to make the PDF indentation more readable. The px-3 class was not enough on some
layouts, such as 'bubble' and 'boxed'.
3. Remove the possibility of having a section appear under both the "Hide Prices" and "Composition"
options. It doesn't make sense to enable both simultaneously, as the user should choose to either
hide the prices or the composition. A PDF with both options enabled is unreadable.
4. Technical refactor of the `_get_child_lines` method. This method is a bit messy and hard
to read. This commit adds a bit of clarity in this method to be more readable in the future.
5. Fix a computation issue in `_get_child_lines`. While iterating on move lines of a hide prices section, we were using the section total amount on each line, which is wrong in case we have subsections. For subsections, we need to recompute the amount to only include the subsection lines.
no-taskWhen an employee adds more of a lunch item they already have in their cart, Odoo now updates only the pending "To order" entry. Previously, already ordered lunch lines for the same product could be increased by mistake, which could lead to incorrect lunch quantities.
Original PR description
**Issue**
When a user has two instances of the same product in their lunch cart, one with state "To order" and one with state "Ordered", and places a new order for that product, both the "To order" and "Ordered" records have their quantity incremented. Only the "To order" record should be updated.
**Steps to Reproduce**
- Add two lunch orders for the same product: one with state "To order" and one with state "Ordered".
- Place a new order for the same product.
- Observe that both records ("To order" and "Ordered") have their quantity incremented.
**Root Cause and Changes Made**
The _find_matching_lines method does not restrict the search to orders with state "new" ("To order"). As a result, it returns all matching records for the product, regardless of their state. When update_quantity is called, it updates the quantity for all these records.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#228712This fix prevents chat and live chat from failing when a channel member is missing profile details that are not needed for the current workflow. The system now safely falls back to an existing "unnamed" label, helping users continue conversations without interruptions.
Original PR description
Sometimes, channel members are received without their partner/guest because it's not important in the flow. However, some part of the JS code assume the persona is always set, resulting in errors. This PR guards access to persona when computing the member name, a fallback to "unnamed" is already in place. task-5184408 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#233134 Forward-Port-Of: odoo/odoo#233056
Users will no longer receive two push notifications for the same message due to an incorrect notification preference check. The mail app now uses the right user preference source, making inbox notifications behave as expected.
Original PR description
**Current behavior before PR:** The `isInbox` condition was always evaluated as false because it incorrectly checked the user's notification preference in the wrong model. This caused users to receive two push notifications for the same message. **Desired behavior after PR is merged:** The `isInbox` condition now checks the user model for notification preferences, ensuring the correct behavior. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233185
The complete contact address now includes the second street address line when it is filled in. This ensures email templates and other uses of the complete address show the full customer or partner address accurately.
Original PR description
Issue: If a user with `street2` wants to utilize the `contact_address_complete` field, the `street2` field is not included. Purpose of this PR: To include the `street2` field in the `contact_address_complete` Steps to reproduce on Runbot: install contact fill in a contact's `street2` create email template that uses the `contact_address_complete` `street2` is omitted from the complete address opw-5186218 Forward-Port-Of: odoo/enterprise#98103
Customers who navigate back during checkout and choose a different delivery address are now handled safely instead of seeing an error page. If the cart is no longer available, the website redirects them back to the shop, preserving a smoother buying experience.
Original PR description
Currently, an error occurs when the user changing the delivery address in the website. **Steps to reproduce:** - Install the `website_sale` module and enable the `Demo` payment provider. - Go to `Website` > `Shop` > `Add a product to Cart` > `View cart` > `Checkout`. - Ensure there are at least two different delivery addresses > `Confirm` > `Pay now`. - Quickly press the browser’s `back button` twice. - Select a different `delivery address`. **Error:** `ValueError: Expected singleton: sale.order()` **Root Cause:** At [1], the code calls `order.ensure_one()`. When the cart (`sale.order`) is empty, leads to an `error`. **Fix:** This commit prevents a traceback on the frontend when a user attempts to change the delivery address and safely redirects them to the shop page. [1]: https://github.com/odoo/odoo/blob/88c9a45ee1ff8dde871865723c3387c059af8289/addons/delivery/models/delivery_carrier.py#L157 sentry-6869972801 Forward-Port-Of: odoo/odoo#226781
The Discuss meeting view now uses larger action buttons that better match the spacious video/avatar layout. This makes call controls easier to see and use during meetings, improving the overall user experience.
Original PR description
Buttons has same size as other discuss actions, which are sized for dense UI like discuss app with message list and composer + panels. In meeting view, the UI is essentially streams / avatar cards. Buttons below need to be sized accordingly, i.e. bigger, which this commit does. Part of Task-5190261 Before <img width="1281" height="899" alt="before" src="https://github.com/user-attachments/assets/3a808149-02c1-41de-b7ef-d2c7681f06c3" /> After <img width="1279" height="902" alt="after" src="https://github.com/user-attachments/assets/3a8e6ff8-6ab2-4d50-a71d-e435e63e28d1" />
This fix stops users from adding tax tags to journal items dated before the tax lock date. It helps protect finalized tax reports from being changed after the reporting period has been locked.
Original PR description
Despite the tax lock date, users are able to modify the tax report by adding tags.
**Steps to reproduce:**
Ensure the tax lock date is set
1. Journal Items list view
2. Edit one/many lines that
- have a date before the tax lock date,
- don't have a tax,
- nor tax tags,
- and is not a tax line.
3. Add a new tax tag
**Issue:**
The tax tags are added and might impact a tax report, when you should have received a user error.
**Cause:**
The `write` function calls the `_check_tax_lock_date` which in turn only checks the existing line instead of the values given in the `write` parameters. Since the line has no existing tax tags the check does not fail.
**Solution:**
Call the tax lock check both before and after writing the move line.
Task-5169152
Forward-Port-Of: odoo/odoo#233032
Forward-Port-Of: odoo/odoo#232380Documentation and clarification updates
A contributor has added their signed Contributor License Agreement for the Odoo project. This records the required legal approval so maintainers can accept future contributions from this person.
Original PR description
Adding my individual Contributor License Agreement (CLA) signature required for contributing to the Odoo project. Current behavior before PR: - The CLA was not signed, which blocks merging of any contribution PRs. Desired behavior after PR is merged: - My CLA signature will be recorded, allowing Odoo maintainers to merge my future contributions. File added: `doc/cla/individual/apurvwajage.md` I confirm I have read and agree to the Odoo Contributor License Agreement (CLA).
Miscellaneous changes
There seems to be a bug in Weblate causing incorrect line wrapping of escaped characters, like `\"`. This bug results in a corrupt PO file because it escapes the `"` character that is supposed to end the string. We manually fix it here, while waiting for a fix in Weblate.
Original PR description
There seems to be a bug in Weblate causing incorrect line wrapping of escaped characters, like `\"`. This bug results in a corrupt PO file because it escapes the `"` character that is supposed to end the string. We manually fix it here, while waiting for a fix in Weblate.
14 changes
Enhancements to existing features
When Uruguay tax authority rejects an electronic invoice and Odoo cancels it, the system now notifies responsible users so the issue is not missed. The update also makes it easier to review and correct invoices whose tax authority status later changes, reducing unnoticed billing inconsistencies.
Original PR description
Added 3 improvements to the process of updating the state of an invoice in Odoo, according to the state in DGI: **For invoices that have been rejected by DGI:** - Added logic to automatically notify…
Added 3 improvements to the process of updating the state of an invoice in Odoo, according to the state in DGI: **For invoices that have been rejected by DGI:** - Added logic to automatically notify relevant users when an electronic invoice (CFE) is rejected by the DGI and, as a result, canceled in the system. The goal is to ensure that there is always someone responsible who is informed to correct and resend the receipt. - Added logs in the terminal to make the debug easier in case we want to identify rejected invoices. **Particular case of an invoice that had been rejected by DGI but the user somehow fixes it and then DGI accepts it:** - Added logic to verify both DGI state and Invoice state and adjust it accordingly when updating invoice DGI status. - Make 'Update DGI status' button always visible to be able to adjust invoices states. **== Context of the Problem ==** Previously, when Odoo detected that a CFE had been rejected by the DGI, the system proceeded to cancel the invoice automatically. However, this process was carried out silently, without generating any notification. This could mean that if no user or salesperson was actively monitoring the status of the receipts, the cancellation would go unnoticed, resulting in invoices that were never corrected or reissued. For the case of a previously rejected and then accepted invoice, we always thought that 'Rejected' state in DGI was a definite state and could not suffer any change. But recently it has been a case that this state changed, creating inconsistencies in Odoo invoices states as they appear as cancelled. With these changes, the user can adjust the invoices state by clicking 'Update DGI status' button. **== Automatic Notification Logic ==** With the new functionality, every time an invoice is automatically canceled due to a DGI rejection, the system posts a message in the document chatter to report the situation. The logic for determining who is notified is as follows: _Scenario 1: Invoice with Internal Followers_ - If the canceled invoice has at least one internal follower (an Odoo user), the system will perform the following actions: - It will post a message in the invoice chatter. - It will tag (@) all internal followers to notify them directly. _Scenario 2: Invoice without Internal Followers_ - If the invoice does not have any internal followers, the system will search for a more general but relevant audience to ensure that the notification is addressed: - It will post a message in the invoice chat. - It will tag (@) all users who belong to the “Accounting Manager” permission group (technical name: group_account_manager). Task ODOO: #[1362](https://latam-localizations.odoo.com/web?debug=1#id=1362&cids=1&menu_id=88&action=131&active_id=16&model=project.task&view_type=form) Task ADHOC: #[54799](https://www.adhoc.inc/odoo//project.task/54799)
Resolved issues and error corrections
This fix improves how Odoo calculates product unit prices in BIS3 electronic invoices when tax-included pricing is used. It prevents small rounding differences from causing Peppol validation failures, helping invoices be accepted correctly.
Original PR description
At the moment, the UBL's Price/PriceAmount node is rounded to the same number of decimals as the database's product price precision. This causes a Peppol schematron validation error due to rule PEPPOL-EN16931-R120 in the case where the user uses tax-included prices. For example, if you have a tax-included unit price of 12.95, a quantity of 8 and a 21% tax, then the tax-excluded subtotal is 85.62. Divide 85.62 by 8 and you get a raw unit price of 10.7025. But if we round to 2 decimal places, we get 10.7 but `10.7 * 8 = 85.6 != 85.62`. Solution: We need to round the unit price to enough decimal places to ensure that unit price * quantity ~= line subtotal (with a tolerance of less than 0.02) opw-5072134
This fix restores Swedish point-of-sale blackbox validation so orders can be processed correctly under Sweden’s fiscal requirements. It also fixes receipt reprint tracking and corrects organisation number formatting, reducing compliance and operational disruption risks for Swedish POS users.
Original PR description
Before this commit, the Swedish blackbox was completely broken in 18.0 because the `push_single_order` function is no longer used. To fix this, the same approach as `pos_blackbox_be` was used, where the `preSyncAllOrders` function was overridden instead. In addition, the old receipt reprinting logic was no longer working, and so it now uses the `nb_print` field to keep track of the number of reprints. Finally, we also forward port a fix from 17.0 (ddbc1fc) to correct the format of the organisation number, which for some reason was not forward ported originally. task-5077448
This fix prevents company bank account setup from failing when a default account-code prefix is missing. It helps affected accounting migrations complete reliably instead of stopping with an error.
Original PR description
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False. ```traceback…
The 'bank_account_code_prefix' field is False by default instead of an empty string. This change ensures proper handling by falling back to an empty string when the field is False.
```traceback
module l10n_co: Running migration [$1.0] end-migrate_update_taxes
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 523, in load_modules
migrations.migrate_module(package, 'end')
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 222, in migrate_module
exec_script(self.cr, installed_version, pyfile, pkg.name, stage, stageformat[stage] % version)
File "/home/odoo/src/odoo/18.0/odoo/modules/migration.py", line 259, in exec_script
mod.migrate(cr, installed_version)
File "/home/odoo/src/odoo/18.0/addons/l10n_co/migrations/1.0/end-migrate_update_taxes.py", line 8, in migrate
env['account.chart.template'].try_loading('co', company)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 160, in try_loading
return self._load(template_code, company, install_demo, force_create)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 228, in _load
self._post_load_data(template_code, company, template_data)
File "/home/odoo/src/enterprise/18.0/account_reports/models/chart_template.py", line 10, in _post_load_data
super()._post_load_data(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 681, in _post_load_data
self._setup_utility_bank_accounts(template_code, company, template_data)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 845, in _setup_utility_bank_accounts
accounts = self.env['account.account']._load_records([
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5526, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5430, in _load_records_create
records = self.create(vals_list)
File "<decorator-gen-208>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 498, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/addons/account/models/account_account.py", line 997, in create
start_code = prefix.ljust(digits - 1, '0') + '1' if len(prefix) < digits else prefix
TypeError: object of type 'bool' has no len()
```
Databases affected by this traceback error:
https://upgrade.odoo.com/odoo/request/3191023/tbg/2150
task-5167397
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prWebsite forms now handle field names that include the “|” character when setting conditional visibility rules. This prevents dependent fields from staying hidden incorrectly, helping form builders use flexible field labels without breaking form behavior.
Original PR description
Before this commit, after selecting a field containing the char "|" for conditional display, the field on which the condition is set will never appear again. This commit enable the use of any characters in form fields Steps to reproduce the bug: - Add a form - Add two fields (A and B) - Rename the field A with a string that contains "|" - Set the field B visibility to "Visible only if" - Set the field A as the visibility condition for field B (field B visible only if field A contains 'hello', for example) - Save the changes - Complete the field A according to the visibility condition (The second field does not appear) task-3893749
Requests for quotation created from approvals now use the currency configured for the product's vendor instead of defaulting to the company currency. This keeps purchase pricing consistent with other RFQ creation flows and avoids currency mismatches when updating existing purchase orders.
Original PR description
Issue: When creating an RFQ from an approval, the created purchase order does not use the currency set on the vendor of the product. Rather, it uses the currency of the company, with the value converted based on the vendor's currency to get the price. This is not consistent with other ways we create RFQs, which all respect the vendor currency. Solution: Pass the vendor's currency into the values sent when creating the purchase order. In the case of modifying an existing purchase order, only modify purchase orders matching vendor's currency. opw-4549937
Fixes an issue where editing the “Terms and conditions” link on a product page could cause an error. The website editor now correctly handles color removal for links styled with special text classes, making this editing flow reliable for users.
Original PR description
Problem: On website > shop > product page, when trying to edit the link of "Terms and conditions", a traceback occurs. Cause: When applying changes on "Terms and conditions" in `shop/product`, `ColorPlugin.removeAllColor()` is called on the `a` element. Its color was applied by the `text-muted` class. This case in color removal was not properly handled. Solution: In `getFonts`, consider elements that have those special classes (e.g., `text-muted`) when processing color removal. Steps to reproduce: 1. Open website/shop. 2. Open any product page. 3. Open the editor. 4. Select the "Terms and conditions" text. 5. Click edit in the link popover. 6. Click apply. 7. Traceback occurs. opw-5130016 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo now routes Peppol participant lookup requests through its central IAP service instead of relying on soon-to-be-deprecated DNS lookup methods. This keeps electronic invoicing connectivity working as Peppol changes its DNS requirements and makes future lookup changes easier to manage centrally.
Original PR description
From November 1st, CNAME DNS will be deprecated for Peppol lookups. From February 1st CNAME lookups will no longer be supported. The replacement are NAPTR DNS records. Multiple solutions were available, such as using DoH (e.g. with cloudflare DNS), but we ended up choosing to proxy DNS requests through IAP to centralize the lookups and make such specs upgrades easier to handle in the future. IAP is now responsible of doing the DNS lookup and fetching the service groups of the found SMP. IAP-side: https://github.com/odoo/iap-apps/pull/1227 task-5179969 Forward-Port-Of: odoo/odoo#232483
The point of sale product grid now displays product cards more consistently on mobile devices. This prevents card sizing conflicts that could make the sales screen look uneven or harder to use.
Original PR description
This commit fixes an issue related to the `product card` which has an enforced `4 /3` aspect ratio. Currently, there are two different grid layouts in `point_of_sale` depending on the breakpoint. On…
This commit fixes an issue related to the `product card` which has an enforced `4 /3` aspect ratio. Currently, there are two different grid layouts in `point_of_sale` depending on the breakpoint. On Mobile, we use a `3 cols` layout with each col being the same size, which conflicts with the grid layout as it try to enforce a specific `width/height` on the element. On other devices, we use an `auto-fill` rule, which provides way more flexibility for items to grow, but even there the aspect-ratio is not working as the item is sized as the other grid items. To fix this issue, we remove the `aspect-ratio` property, which was not affecting the design of the item and rely on the default grid sizing behaviour, to prevent any issue. task-4965395 | 18.0 and above | This PR | |--------|--------| | <img width="391" height="844" alt="image" src="https://github.com/user-attachments/assets/a191bfcf-20f6-4621-832b-a40ed42c2358" /> | <img width="391" height="844" alt="image" src="https://github.com/user-attachments/assets/7f07000e-b0e5-411e-bce6-12a5072bb854" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The sale product catalog now shows the discounted price for a single sale order line, instead of showing the original unit price. This prevents pricing confusion and keeps the catalog display aligned with the actual order total.
Original PR description
Description of the issue/feature this PR addresses: When using the product catalog in sale orders, if a sale order line has a discount applied via the `discount` field, the catalog displays the base…
Description of the issue/feature this PR addresses: When using the product catalog in sale orders, if a sale order line has a discount applied via the `discount` field, the catalog displays the base `price_unit` instead of the discounted price. This creates an inconsistency between what's shown in the catalog and the actual price in the order line. Current behavior before PR: - A sale order line with price_unit=120.00 and discount=15% shows subtotal=102.00 in the order - The product catalog shows price=120.00 (without discount applied) - This only happens when `len(self) == 1` in `_get_product_catalog_lines_data()` - The multi-line case (`elif self:`) correctly calculates the price using pricelist Desired behavior after PR is merged: - The product catalog should show price=102.00 (with discount applied) - Consistency between catalog price and order line subtotal - The discount field is properly considered in the price calculation for single lines - Behavior matches the multi-line case where pricelist correctly calculates discounted prices --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The sales product catalog now shows prices that correctly reflect discounts for products already added to an order. This prevents misleading catalog prices and helps sales teams quote customers accurately.
Original PR description
Catalog prices do not consider discounts when displayed separately from the unit price on the order line (if any for a given product). It was fixed for the /update_order_line_info route with 5d1837e47c20f04458472658c4f8ea71284fb6ca, but the issue still remained when fetching the original catalog data on opening, through the /order_lines_info route. This only happened when the product was already added to the order, because in this case we avoid recomputing the pricelist price and use the existing sale order line price. This commit makes sure that the sale order line discount field is correctly considered in that case, and also adds tests to cover the catalog more extensively. Fixes #232219 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures Saudi e-invoicing configuration checks still run when a company has no country set. It helps prevent misconfigured invoices from causing errors that can block automated EDI processing jobs.
Original PR description
ZATCA invoice misconfigurations are only checked for if the company has Saudi Arabia set as its country. However, ZATCA EDIs can be generated without Saudi Arabia set as the country. Thus, companies without a company set can create EDI documents for misconfigured invoices. This may cause traceback errors which prevent the "EDI : Perform web services operations" cron from running at all. This commit ensures that configuration checks are run on companies without countries set (and adds a relevant unit test). opw-5057792 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#231255
Lithuanian payslips no longer apply the employee pension contribution twice when pension accumulation is enabled. This prevents overstating payroll deductions and helps ensure payslips match expected Lithuanian social security rules.
Original PR description
**Issue**
When generating a payslip for an employee with the `l10n_lt_pension` setting enabled on the contract ("Participate to pension accumulation system"):
- the SSC is raised from 19.5% to 22.5%
- a 3% pension contribution ("Pension Scheme") is added This effectively doubles the expected contribution.
Various sources (e.g. https://taxsummaries.pwc.com/lithuania/individual/other-taxes) seem to show this is not correct.
opw-5067664
Forward-Port-Of: odoo/enterprise#95880Contact complete addresses now include the second street address line when it is filled in. This ensures email templates and other uses of the complete address show the full mailing address, reducing omissions in customer communications.
Original PR description
Issue: If a user with `street2` wants to utilize the `contact_address_complete` field, the `street2` field is not included. Purpose of this PR: To include the `street2` field in the `contact_address_complete` Steps to reproduce on Runbot: install contact fill in a contact's `street2` create email template that uses the `contact_address_complete` `street2` is omitted from the complete address opw-5186218 Forward-Port-Of: odoo/enterprise#98103
9 changes
Enhancements to existing features
The accounting accrual wizard is being prepared to support more flexible reversal entry creation. This matters for businesses that need accruals spread across multiple periods, helping future customizations match reversals with actual invoices more accurately.
Original PR description
Add a dedicated hook method to facilitate customization of reversal entry generation in the accrued orders wizard. Reason: The current implementation creates a single reversal entry that is applied in the next period. For scenarios requiring accrual allocation across multiple periods, modules need the ability to generate multiple reversal entries (one per period) to properly net-off against actual invoices --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
Fixed an issue where point-of-sale imports of sale orders could skip lot-tracked products when some quantities were not assigned to existing lots. This helps cashiers process sale orders more reliably without manually re-adding missing product lines.
Original PR description
## Issue: When you have a Sale Order containing products tracked by lots, and there are not enough quantities in the existing lots, importing the SO into the POS does not add the sub-lines that are not linked to a lot However, it is still possible to add these products manually in the POS interface ## Cause: The sub lines are only added for the quantities linked to lots using a loop on `lot_names`: https://github.com/odoo/odoo/blob/47898975c7af83559ea95fb86e07c19feea1d2d7/addons/pos_sale/static/src/app/order_management_screen/sale_order_management_screen/sale_order_management_screen.js#L257-L269 If there is no `lot_names` or there is missing quantity, the condition doesn’t match to add the line and the sub line is skipped ## Steps to reproduce: - Create a storable product tracked by lots - Create a Sale Order for that product - Open a POS session and open the Sale Order - Before the fix, product lines without lots were not added automatically opw-5099616
This fixes a compatibility issue in Peppol partner handling so it continues to work with the older requests library version supported by Odoo 17. It helps avoid failures in deployments using the standard dependency versions.
Original PR description
JSONDecodeError was added in requests 2.28 and odoo 17 should be compatible with requests 2.22 see https://github.com/odoo/odoo/blob/17.0/requirements.txt#L76 no-task
Batch payments now show a clear warning when SEPA Credit Transfer recipients are missing required country or city details for structured addresses. This helps users correct partner records before generating payment XML files that could become invalid under the upcoming rules.
Original PR description
Starting from November 15th, 2026, SEPA Credit Transfer (SCT) payments require both the partner's country and city to be defined when using structured addresses. If missing, the generated XML file will be invalid. This change adds a non-blocking red banner on the batch payment form to warn users and provide a link to review the affected partners. task-5156613
Repair order users can no longer enter a serial number on a new repair line before that line has been saved. This prevents the serial number from disappearing on save and helps ensure tracked products remain correctly assigned.
Original PR description
When creating a repair order, if you add a line and assign a serial number before saving the line, the serial number is removed when saving. Steps to reproduce: - Create a repair order and save it. - Add a repair line with a product tracked by serial number. - Without saving the repair order, add a serial number on the line. - Save the repair order. - You will notice that the serial number is no longer assigned to the repair line. This PR fixes the issue by making the serial number field read-only until the repair line is saved. opw-5156267
This update fixes several visual issues introduced by the customer portal redesign, including overflowing sidebars, missing spacing above the footer, inconsistent alert styling, and a missing border around the chatter composer. These changes make portal pages easier to read and use across sales, purchases, accounting, and timesheet views.
Original PR description
This PR aims to fix issues introduced after the portal redesign. task-3714408 part of task-3703251 - Requires https://github.com/odoo/enterprise/pull/55519 ----------- ## Overflowing sidebar With the…
This PR aims to fix issues introduced after the portal redesign. task-3714408 part of task-3703251 - Requires https://github.com/odoo/enterprise/pull/55519 ----------- ## Overflowing sidebar With the portal redesign, we now use a two columns layout with a `d-inline-block` on the left one (sidebar), which allows the sidebar column to grow depending on its content. While this brought more fluidity to the layout, it also introduced an issue, having a very long amount would make the sidebar overflow on the right column. ## Missing padding-bottom on container Commit[1] removed a `padding-bottom` class from the container in order to reduce the vertical whitespace, but this introduced an issue in some cases, depending on the footer in use. By removing the `padding-bottom` utility class, the content of the customer portal would sometimes stick to the footer of the page. ## View timesheet button display Depending on the sidebar layout, the View timesheet button will be display next to two other buttons, and with a `btn-link` class. We adapt the styling and position of the button to make it consistent with other views in which it is also displayed. ## Alerts While fixing the sidebar issue, this PR also fix some inconsistencies in the alerts used within Portal. Mainly about text alignment, and alerts with a link that were missing an `alert-link` class.
This update documents an unused website event speaker biography section so maintainers understand why it remains present in the stable version. It helps avoid confusion during future maintenance without changing how events appear or function for users.
Original PR description
Problem introduced at [1] (see [2]). In stable, this comments the code to explain the dead code presence. In master, that snippet will be removed, as nobody seemed to have missed him for 4+ major versions and its structure is not perfect (overflow hidden...). Thankfully it should not come with any compatibility issue as it was not associated with any JS/CSS). Maybe a new equivalent will be introduced in master later on. [1]: https://github.com/odoo/odoo/commit/b5c87d86cad1aa2b44f805da0b2d6635aeb85b96 [2]: https://github.com/odoo/odoo/pull/68644#discussion_r903721785 task-4084801
Odoo now prevents the built-in Public User from being deleted, avoiding a situation where the login page could become inaccessible. This keeps databases reachable even when the Website app is not installed, and adds test coverage to confirm the safeguard works.
Original PR description
Steps to Reproduce:
1. Create a database without installing the Website module.
2. Navigate to archived users and delete the "Public User."
3. Attempt to log in to the database from another browser or incognito
mode.
4. An internal server error occurs because the public user does not
exist, making the login page inaccessible.
Issue:
Previously, it was possible to delete the public user, leading to an
internal server error due to its absence, which prevented public access
to the login page.
Solution:
- Implemented a restriction to prevent the deletion of the public user,
similar to portal and default users.
- Added a test case to validate this functionality and ensure the
public user cannot be deleted.
task-4423568Spreadsheet version history now reuses company currency information more efficiently instead of making an extra server request. This fixes a version history issue and improves loading performance for users working with spreadsheets.
Original PR description
The perfomance commit added in https://github.com/odoo/odoo/pull/151725 did not account for the version history action that does not inherit from `AbstractSpreadsheetAction`. this missing value trickled down to a bug only detectable in the VersionHistory action and which is addressed in https://github.com/odoo/odoo/pull/232985 This commit adds the same performance to VersionHistory action. Task-5187293